Browse Source

Remove Memcache, improve test coverage, fix bugs

Timothy J. Warren 1 month ago
parent
commit
65fd726e2c

+ 5
- 0
CHANGELOG.md View File

@@ -0,0 +1,5 @@
1
+# Changelog
2
+
3
+## 2.0.0
4
+* Removed `Memcache` integration, as the extension does not seem to be maintained
5
+* Increased required PHP version to 7.1

+ 2
- 3
README.md View File

@@ -8,7 +8,6 @@ backends
8 8
 
9 9
 ## Cache Backends
10 10
 * Apcu
11
-* Memcache
12 11
 * Memcached
13 12
 * Redis
14 13
 * Null - no persistence
@@ -46,7 +45,7 @@ structure is like so:
46 45
 ```php
47 46
 <?php
48 47
 $config = [
49
-	'driver' => 'null', // null, apcu, redis, memcache, memcached
48
+	'driver' => 'null', // null, apcu, redis, memcached
50 49
 	'connection' => [
51 50
 		// Optional (For some drivers):
52 51
 		// driver setup, see below for the structure for each
@@ -62,7 +61,7 @@ $config = [
62 61
 
63 62
 Below are the connection arrays for each backend:
64 63
 
65
-Memcache / Memcached:
64
+Memcached:
66 65
 ```php
67 66
 <?php
68 67
 $config['connection'] = [

+ 3
- 3
build/header_comment.txt View File

@@ -3,12 +3,12 @@
3 3
  *
4 4
  * A Caching library implementing psr/cache
5 5
  *
6
- * PHP version 7.0
6
+ * PHP version 7.1
7 7
  *
8 8
  * @package     Banker
9 9
  * @author      Timothy J. Warren <tim@timshomepage.net>
10
- * @copyright   2016 - 2017  Timothy J. Warren
10
+ * @copyright   2016 - 2018  Timothy J. Warren
11 11
  * @license     http://www.opensource.org/licenses/mit-license.html  MIT License
12
- * @version     1.0.1
12
+ * @version     2.0.0
13 13
  * @link        https://git.timshomepage.net/timw4mail/banker
14 14
  */

+ 3
- 2
composer.json View File

@@ -5,7 +5,6 @@
5 5
 	"keywords": [
6 6
 		"cache",
7 7
 		"redis",
8
-		"memcache",
9 8
 		"memcached",
10 9
 		"psr-6",
11 10
 		"psr6"
@@ -24,6 +23,8 @@
24 23
 		}
25 24
 	},
26 25
 	"require": {
26
+		"php": "^7.1",
27
+		"ext-json": "*",
27 28
 		"predis/predis": "^1.1",
28 29
 		"psr/log": "^1.0",
29 30
 		"psr/cache": "^1.0.1"
@@ -42,7 +43,7 @@
42 43
 	},
43 44
 	"suggest": {
44 45
 		"monolog/monolog": "A good standard logging library",
45
-		"ext-memcache": "Required for Memcache backend",
46
+		"ext-apcu": "Required for apcu driver",
46 47
 		"ext-memcached": "Required for Memcached backend",
47 48
 		"ext-phpiredis": "Improves speed of Redis driver"
48 49
 	},

+ 21
- 7
src/Driver/AbstractDriver.php View File

@@ -25,13 +25,6 @@ abstract class AbstractDriver implements DriverInterface, LoggerAwareInterface {
25 25
 
26 26
 	use LoggerTrait;
27 27
 
28
-	/**
29
-	 * The object encapsulating the connection to the cache backend
30
-	 *
31
-	 * @var mixed
32
-	 */
33
-	protected $conn;
34
-
35 28
 	/**
36 29
 	 * Data to be stored later
37 30
 	 *
@@ -51,4 +44,25 @@ abstract class AbstractDriver implements DriverInterface, LoggerAwareInterface {
51 44
 	 * Common destructor
52 45
 	 */
53 46
 	abstract public function __destruct();
47
+
48
+	/**
49
+	 * Retrieve a set of values by their cache key
50
+	 *
51
+	 * @param string[] $keys
52
+	 * @return array
53
+	 */
54
+	public function getMultiple(array $keys = []): array
55
+	{
56
+		$output = [];
57
+
58
+		foreach ($keys as $key)
59
+		{
60
+			if ($this->exists($key))
61
+			{
62
+				$output[$key] = $this->get($key);
63
+			}
64
+		}
65
+
66
+		return $output;
67
+	}
54 68
 }

+ 6
- 13
src/Driver/ApcuDriver.php View File

@@ -29,7 +29,7 @@ use Aviat\Banker\Exception\CacheException;
29 29
  * Memcached cache backend
30 30
  */
31 31
 class ApcuDriver extends AbstractDriver {
32
-	
32
+
33 33
 	/**
34 34
 	 * Constructor
35 35
 	 *
@@ -40,7 +40,7 @@ class ApcuDriver extends AbstractDriver {
40 40
 	{
41 41
 		// noop
42 42
 	}
43
-	
43
+
44 44
 	/**
45 45
 	 * Destructor
46 46
 	 */
@@ -80,14 +80,7 @@ class ApcuDriver extends AbstractDriver {
80 80
 	public function getMultiple(array $keys = []): array
81 81
 	{
82 82
 		$status = FALSE;
83
-		$output = apcu_fetch($keys, $status);
84
-		
85
-		if ($status === FALSE || !is_array($output))
86
-		{
87
-			return [];
88
-		}
89
-		
90
-		return $output;
83
+		return apcu_fetch($keys, $status);
91 84
 	}
92 85
 
93 86
 	/**
@@ -120,7 +113,7 @@ class ApcuDriver extends AbstractDriver {
120 113
 	 */
121 114
 	public function delete(string $key): bool
122 115
 	{
123
-		return apcu_delete($key);
116
+		return (bool) apcu_delete($key);
124 117
 	}
125 118
 
126 119
 	/**
@@ -131,7 +124,7 @@ class ApcuDriver extends AbstractDriver {
131 124
 	 */
132 125
 	public function deleteMultiple(array $keys = []): bool
133 126
 	{
134
-		return apcu_delete($keys);
127
+		return (bool) apcu_delete($keys);
135 128
 	}
136 129
 
137 130
 	/**
@@ -159,7 +152,7 @@ class ApcuDriver extends AbstractDriver {
159 152
 			return apcu_store($key, $value, $expires);
160 153
 		}
161 154
 
162
-		$this->getLogger()->warn("Tried to set expiration on a key that does not exist");
155
+		$this->getLogger()->log('warning', 'Tried to set expiration on a key that does not exist');
163 156
 
164 157
 		return FALSE;
165 158
 	}

+ 0
- 162
src/Driver/MemcacheDriver.php View File

@@ -1,162 +0,0 @@
1
-<?php declare(strict_types=1);
2
-/**
3
- * Banker
4
- *
5
- * A Caching library implementing psr/cache
6
- *
7
- * PHP version 7.0
8
- *
9
- * @package     Banker
10
- * @author      Timothy J. Warren <tim@timshomepage.net>
11
- * @copyright   2016 - 2017  Timothy J. Warren
12
- * @license     http://www.opensource.org/licenses/mit-license.html  MIT License
13
- * @version     1.0.1
14
- * @link        https://git.timshomepage.net/timw4mail/banker
15
- */
16
-namespace Aviat\Banker\Driver;
17
-
18
-use Aviat\Banker\Exception\CacheException;
19
-use Memcache;
20
-
21
-/**
22
- * Redis cache backend
23
- */
24
-class MemcacheDriver extends AbstractDriver {
25
-
26
-	/**
27
-	 * Driver for PHP Memcache extension
28
-	 *
29
-	 * @param array $config
30
-	 * @param array $options
31
-	 * @throws CacheException
32
-	 */
33
-	public function __construct(array $config = [], array $options = [])
34
-	{
35
-		if ( ! class_exists('Memcache'))
36
-		{
37
-			throw new CacheException('Memcache driver requires the PHP memcache extension');
38
-		}
39
-
40
-		$this->conn = new Memcache();
41
-
42
-		$method = ($config['persistent'] === TRUE) ? 'pconnect' : 'connect';
43
-
44
-		$this->conn->$method($config['host'], (int) $config['port']);
45
-	}
46
-
47
-	/**
48
-	 * Disconnect from memcached server
49
-	 */
50
-	public function __destruct()
51
-	{
52
-		$this->conn->close();
53
-	}
54
-
55
-	/**
56
-	 * See if a key currently exists in the cache
57
-	 *
58
-	 * @param string $key
59
-	 * @return bool
60
-	 */
61
-	public function exists(string $key): bool
62
-	{
63
-		return $this->conn->get($key) !== FALSE;
64
-	}
65
-
66
-	/**
67
-	 * Get the value for the selected cache key
68
-	 *
69
-	 * @param string $key
70
-	 * @return mixed
71
-	 */
72
-	public function get(string $key)
73
-	{
74
-		return $this->conn->get($key);
75
-	}
76
-
77
-	/**
78
-	 * Retrieve a set of values by their cache key
79
-	 *
80
-	 * @param string[] $keys
81
-	 * @return array
82
-	 */
83
-	public function getMultiple(array $keys = []): array
84
-	{
85
-		return $this->conn->get($keys);
86
-	}
87
-
88
-	/**
89
-	 * Set a cached value
90
-	 *
91
-	 * @param string $key
92
-	 * @param mixed $value
93
-	 * @param int $expires
94
-	 * @return DriverInterface
95
-	 */
96
-	public function set(string $key, $value, int $expires = 0): DriverInterface
97
-	{
98
-		if ($this->exists($key))
99
-		{
100
-			$this->conn->replace($key, $value, 0, $expires);
101
-		}
102
-		else
103
-		{
104
-			$this->conn->set($key, $value, 0, $expires);
105
-		}
106
-
107
-		return $this;
108
-	}
109
-
110
-	/**
111
-	 * Remove an item from the cache
112
-	 *
113
-	 * @param string $key
114
-	 * @return boolean
115
-	 */
116
-	public function delete(string $key): bool
117
-	{
118
-		return $this->conn->delete($key);
119
-	}
120
-
121
-	/**
122
-	 * Remove multiple items from the cache
123
-	 *
124
-	 * @param string[] $keys
125
-	 * @return boolean
126
-	 */
127
-	public function deleteMultiple(array $keys = []): bool
128
-	{
129
-		// Iteratively delete each item, using a boolean
130
-		// 'and' operation to return false if any deletion fails
131
-		return \array_reduce($keys, function($prev, $key) {
132
-			return $prev && $this->conn->delete($key);
133
-		}, TRUE);
134
-	}
135
-
136
-	/**
137
-	 * Empty the cache
138
-	 *
139
-	 * @return boolean
140
-	 */
141
-	public function flush(): bool
142
-	{
143
-		return $this->conn->flush();
144
-	}
145
-
146
-	/**
147
-	 * Set the specified key to expire at the given time
148
-	 *
149
-	 * @param string $key
150
-	 * @param int $expires
151
-	 * @return boolean
152
-	 */
153
-	public function expiresAt(string $key, int $expires): bool
154
-	{
155
-		$value = $this->get($key);
156
-		$timediff = $expires - time();
157
-
158
-		$this->set($key, $value, $timediff);
159
-
160
-		return TRUE;
161
-	}
162
-}

+ 7
- 5
src/Driver/MemcachedDriver.php View File

@@ -28,18 +28,19 @@ class MemcachedDriver extends AbstractDriver {
28 28
 	/**
29 29
 	 * Driver for PHP Memcache extension
30 30
 	 *
31
+	 * @codeCoverageIgnore
31 32
 	 * @param array $config
32 33
 	 * @param array $options
33 34
 	 * @throws CacheException
34 35
 	 */
35 36
 	public function __construct(
36
-		array $config = ['host' => '127.0.0.1', 'port' => '11211'], 
37
+		array $config = ['host' => '127.0.0.1', 'port' => '11211'],
37 38
 		array $options = []
38 39
 	)
39 40
 	{
40 41
 		if ( ! class_exists('Memcached'))
41 42
 		{
42
-			throw new CacheException("Memcached driver requires memcached extensions");
43
+			throw new CacheException('Memcached driver requires memcached extension');
43 44
 		}
44 45
 
45 46
 		try
@@ -133,7 +134,7 @@ class MemcachedDriver extends AbstractDriver {
133 134
 	 */
134 135
 	public function delete(string $key): bool
135 136
 	{
136
-		return $this->conn->delete($key);
137
+		return (bool) $this->conn->delete($key);
137 138
 	}
138 139
 
139 140
 	/**
@@ -144,7 +145,8 @@ class MemcachedDriver extends AbstractDriver {
144 145
 	 */
145 146
 	public function deleteMultiple(array $keys = []): bool
146 147
 	{
147
-		return $this->conn->deleteMulti($keys);
148
+		$deleted = $this->conn->deleteMulti($keys);
149
+		return ($keys <=> $deleted) === 0;
148 150
 	}
149 151
 
150 152
 	/**
@@ -171,7 +173,7 @@ class MemcachedDriver extends AbstractDriver {
171 173
 			return $this->conn->touch($key, $expires);
172 174
 		}
173 175
 
174
-		$this->getLogger()->warn("Tried to set expiration on a key that does not exist");
176
+		$this->getLogger()->log('warning','Tried to set expiration on a key that does not exist');
175 177
 
176 178
 		return FALSE;
177 179
 	}

+ 2
- 20
src/Driver/NullDriver.php View File

@@ -67,29 +67,11 @@ class NullDriver extends AbstractDriver {
67 67
 	 */
68 68
 	public function get(string $key)
69 69
 	{
70
-		return ($this->exists($key))
70
+		return $this->exists($key)
71 71
 			? $this->store[$key]
72 72
 			: NULL;
73 73
 	}
74 74
 
75
-	/**
76
-	 * Retrieve a set of values by their cache key
77
-	 *
78
-	 * @param string[] $keys
79
-	 * @return array
80
-	 */
81
-	public function getMultiple(array $keys = []): array
82
-	{
83
-		$output = [];
84
-
85
-		foreach($keys as $key)
86
-		{
87
-			$output[$key] = $this->get($key);
88
-		}
89
-
90
-		return $output;
91
-	}
92
-
93 75
 	/**
94 76
 	 * Set a cached value
95 77
 	 *
@@ -155,6 +137,6 @@ class NullDriver extends AbstractDriver {
155 137
 	public function expiresAt(string $key, int $expires): bool
156 138
 	{
157 139
 		//noop
158
-		return TRUE;
140
+		return array_key_exists($key, $this->store);
159 141
 	}
160 142
 }

+ 3
- 21
src/Driver/RedisDriver.php View File

@@ -15,7 +15,6 @@
15 15
  */
16 16
 namespace Aviat\Banker\Driver;
17 17
 
18
-use Aviat\Banker\Exception\CacheException;
19 18
 use Predis\Client;
20 19
 
21 20
 /**
@@ -33,6 +32,7 @@ class RedisDriver extends AbstractDriver {
33 32
 	/**
34 33
 	 * RedisDriver constructor.
35 34
 	 *
35
+	 * @codeCoverageIgnore
36 36
 	 * @param array $config
37 37
 	 * @param array $options - Predis library connection options
38 38
 	 * @throws CacheException
@@ -78,24 +78,6 @@ class RedisDriver extends AbstractDriver {
78 78
 		return unserialize($raw);
79 79
 	}
80 80
 
81
-	/**
82
-	 * Retrieve a set of values by their cache key
83
-	 *
84
-	 * @param string[] $keys
85
-	 * @return array
86
-	 */
87
-	public function getMultiple(array $keys = []): array
88
-	{
89
-		$output = [];
90
-
91
-		foreach($keys as $key)
92
-		{
93
-			$output[$key] = $this->get($key);
94
-		}
95
-
96
-		return $output;
97
-	}
98
-
99 81
 	/**
100 82
 	 * Set a cached value
101 83
 	 *
@@ -110,7 +92,7 @@ class RedisDriver extends AbstractDriver {
110 92
 
111 93
 		if ($expires !== 0)
112 94
 		{
113
-			$this->conn->set($key, $value, "EX", $expires);
95
+			$this->conn->set($key, $value, 'EX', $expires);
114 96
 		}
115 97
 		else
116 98
 		{
@@ -140,7 +122,7 @@ class RedisDriver extends AbstractDriver {
140 122
 	public function deleteMultiple(array $keys = []): bool
141 123
 	{
142 124
 		$res = $this->conn->del(...$keys);
143
-		return $res === count($keys);
125
+		return $res === \count($keys);
144 126
 	}
145 127
 
146 128
 	/**

+ 4
- 3
src/Item.php View File

@@ -101,7 +101,7 @@ class Item implements CacheItemInterface {
101 101
 	{
102 102
 		if ($this->isHit())
103 103
 		{
104
-			return $this->driver->get($this->key);
104
+			return $this->value ?? $this->driver->get($this->key);
105 105
 		}
106 106
 
107 107
 		return NULL;
@@ -118,7 +118,7 @@ class Item implements CacheItemInterface {
118 118
 	 */
119 119
 	public function isHit(): bool
120 120
 	{
121
-		return $this->driver->exists($this->key);
121
+		return isset($this->value) || $this->driver->exists($this->key);
122 122
 	}
123 123
 
124 124
 	/**
@@ -202,7 +202,8 @@ class Item implements CacheItemInterface {
202 202
 
203 203
 			return $setResult && $expResult;
204 204
 		}
205
-		else if ($this->ttl !== NULL && $this->ttl !== 0)
205
+
206
+		if ($this->ttl !== NULL && $this->ttl !== 0)
206 207
 		{
207 208
 			return (bool) $this->driver->set($this->key, $this->value, $this->ttl);
208 209
 		}

+ 5
- 2
src/ItemCollection.php View File

@@ -17,13 +17,16 @@ namespace Aviat\Banker;
17 17
 
18 18
 use Psr\Cache\CacheItemInterface;
19 19
 
20
+use ArrayIterator;
21
+use JsonSerializable;
22
+
20 23
 /**
21
- * Collection of Psr\Cache\CacheItemIterface objects to be returned by getItems
24
+ * Collection of Psr\Cache\CacheItemInterface objects to be returned by getItems
22 25
  *
23 26
  * @see http://php.net/manual/en/class.arrayiterator.php
24 27
  * @see http://php.net/manual/en/class.jsonserializable.php
25 28
  */
26
-class ItemCollection extends \ArrayIterator implements \JsonSerializable {
29
+class ItemCollection extends ArrayIterator implements JsonSerializable {
27 30
 
28 31
 	/**
29 32
 	 * The raw CacheItemInterface objects

+ 2
- 2
src/LoggerTrait.php View File

@@ -35,7 +35,7 @@ trait LoggerTrait {
35 35
 	 *
36 36
 	 * @return LoggerInterface
37 37
 	 */
38
-	protected function getLogger()
38
+	protected function getLogger(): LoggerInterface
39 39
 	{
40 40
 		if ($this->logger === NULL)
41 41
 		{
@@ -50,7 +50,7 @@ trait LoggerTrait {
50 50
 	 * @param LoggerInterface $logger
51 51
 	 * @return self
52 52
 	 */
53
-	public function setLogger(LoggerInterface $logger)
53
+	public function setLogger(LoggerInterface $logger): self
54 54
 	{
55 55
 		$this->logger = $logger;
56 56
 

+ 24
- 33
src/Pool.php View File

@@ -24,7 +24,7 @@ use Psr\Log\{LoggerAwareInterface, LoggerInterface};
24 24
 /**
25 25
  * The main cache manager
26 26
  */
27
-class Pool implements CacheItemPoolInterface, LoggerAwareInterface {
27
+final class Pool implements CacheItemPoolInterface, LoggerAwareInterface {
28 28
 
29 29
 	use LoggerTrait;
30 30
 
@@ -46,12 +46,13 @@ class Pool implements CacheItemPoolInterface, LoggerAwareInterface {
46 46
 	 * Set up the cache backend
47 47
 	 *
48 48
 	 * @param array $config
49
+	 * @param LoggerInterface $logger
49 50
 	 */
50
-	public function __construct(array $config, LoggerInterface $logger = NULL)
51
+	public function __construct(array $config, ?LoggerInterface $logger = NULL)
51 52
 	{
52 53
 		$this->driver = $this->loadDriver($config);
53 54
 
54
-		if ( ! is_null($logger))
55
+		if ($logger !== NULL)
55 56
 		{
56 57
 			$this->setLogger($logger);
57 58
 		}
@@ -75,7 +76,7 @@ class Pool implements CacheItemPoolInterface, LoggerAwareInterface {
75 76
 	 */
76 77
 	public function getItem($key): CacheItemInterface
77 78
 	{
78
-		if ( ! is_string($key))
79
+		if ( ! \is_string($key))
79 80
 		{
80 81
 			throw new InvalidArgumentException();
81 82
 		}
@@ -86,8 +87,7 @@ class Pool implements CacheItemPoolInterface, LoggerAwareInterface {
86 87
 			return $this->deferred[$key];
87 88
 		}
88 89
 
89
-		$item = new Item($this->driver, $key);
90
-		return $item;
90
+		return new Item($this->driver, $key);
91 91
 	}
92 92
 
93 93
 	/**
@@ -113,27 +113,18 @@ class Pool implements CacheItemPoolInterface, LoggerAwareInterface {
113 113
 			return new ItemCollection([]);
114 114
 		}
115 115
 
116
+		// Get the set of items selected
117
+		$items = [];
116 118
 		foreach($keys as $key)
117 119
 		{
118
-			if ( ! is_string($key))
120
+			if ( ! \is_string($key))
119 121
 			{
120 122
 				throw new InvalidArgumentException();
121 123
 			}
122
-		}
123 124
 
124
-		// Get the set of items selected
125
-		$items = [];
126
-		$rawItems = $this->driver->getMultiple($keys);
127
-		foreach($rawItems as $key => $val)
128
-		{
129
-			if (array_key_exists($key, $this->deferred))
130
-			{
131
-				$items[$key] = $this->deferred[$key];
132
-			}
133
-			else
134
-			{
135
-				$items[$key] = new Item($this->driver, $key);
136
-			}
125
+			$items[$key] = array_key_exists($key, $this->deferred)
126
+				? $this->deferred[$key]
127
+				: new Item($this->driver, $key);
137 128
 		}
138 129
 
139 130
 		return new ItemCollection($items);
@@ -156,9 +147,9 @@ class Pool implements CacheItemPoolInterface, LoggerAwareInterface {
156 147
 	 * @return bool
157 148
 	 *   True if item exists in the cache, false otherwise.
158 149
 	 */
159
-	public function hasItem($key)
150
+	public function hasItem($key): bool
160 151
 	{
161
-		if ( ! is_string($key))
152
+		if ( ! \is_string($key))
162 153
 		{
163 154
 			throw new InvalidArgumentException();
164 155
 		}
@@ -198,7 +189,7 @@ class Pool implements CacheItemPoolInterface, LoggerAwareInterface {
198 189
 	 */
199 190
 	public function deleteItem($key): bool
200 191
 	{
201
-		if ( ! is_string($key))
192
+		if ( ! \is_string($key))
202 193
 		{
203 194
 			throw new InvalidArgumentException();
204 195
 		}
@@ -207,10 +198,8 @@ class Pool implements CacheItemPoolInterface, LoggerAwareInterface {
207 198
 		{
208 199
 			return FALSE;
209 200
 		}
210
-		else
211
-		{
212
-			return $this->driver->delete($key);
213
-		}
201
+
202
+		return $this->driver->delete($key);
214 203
 	}
215 204
 
216 205
 	/**
@@ -230,7 +219,7 @@ class Pool implements CacheItemPoolInterface, LoggerAwareInterface {
230 219
 	{
231 220
 		foreach ($keys as $key)
232 221
 		{
233
-			if ( ! is_string($key))
222
+			if ( ! \is_string($key))
234 223
 			{
235 224
 				throw new InvalidArgumentException();
236 225
 			}
@@ -264,7 +253,9 @@ class Pool implements CacheItemPoolInterface, LoggerAwareInterface {
264 253
 	 */
265 254
 	public function saveDeferred(CacheItemInterface $item): bool
266 255
 	{
267
-		$this->deferred[$item->getKey()] = $item;
256
+		$key = $item->getKey();
257
+		$this->deferred[$key] = $item;
258
+
268 259
 		return TRUE;
269 260
 	}
270 261
 
@@ -302,11 +293,11 @@ class Pool implements CacheItemPoolInterface, LoggerAwareInterface {
302 293
 	 * @param array $driverConfig
303 294
 	 * @return DriverInterface
304 295
 	 */
305
-	protected function loadDriver(array $driverConfig): DriverInterface
296
+	protected function loadDriver(array $driverConfig = []): DriverInterface
306 297
 	{
307
-		$driver = ucfirst(strtolower($driverConfig['driver']));
298
+		$driver = ucfirst(strtolower($driverConfig['driver'] ?? 'null'));
308 299
 		$class = __NAMESPACE__ . "\\Driver\\${driver}Driver";
309
-		
300
+
310 301
 		$driverConfig['connection'] = $driverConfig['connection'] ?? [];
311 302
 		$driverConfig['options'] = $driverConfig['options'] ?? [];
312 303
 

+ 48
- 4
tests/Driver/DriverTestBase.php View File

@@ -21,14 +21,15 @@ class DriverTestBase extends TestCase {
21 21
 
22 22
 	protected $driver;
23 23
 
24
-	public function tearDown()
24
+	public function tearDown(): void
25 25
 	{
26 26
 		$this->driver->__destruct();
27 27
 	}
28 28
 
29
-	public function testGetSet()
29
+	public function testGetSet(): void
30 30
 	{
31 31
 		$this->driver->set('foo', 'bar');
32
+		$this->assertTrue($this->driver->exists('foo'));
32 33
 		$this->assertEquals('bar', $this->driver->get('foo'));
33 34
 
34 35
 		$bar = [
@@ -42,7 +43,13 @@ class DriverTestBase extends TestCase {
42 43
 		$this->assertEquals($bar, $this->driver->get('bar'));
43 44
 	}
44 45
 
45
-	public function testGetMultiple()
46
+	public function testGetMultipleOnBadKey(): void
47
+	{
48
+		$actual = $this->driver->getMultiple(['x','y']);
49
+		$this->assertEquals([], $actual);
50
+	}
51
+
52
+	public function testGetMultiple(): void
46 53
 	{
47 54
 		$this->driver->set('foo', ['bar']);
48 55
 		$this->driver->set('bar', (object) [
@@ -69,9 +76,46 @@ class DriverTestBase extends TestCase {
69 76
 		$this->assertEquals($expected, $actual);
70 77
 	}
71 78
 
72
-	public function testSetWithExpires()
79
+	public function testSetWithExpires(): void
73 80
 	{
74 81
 		$this->driver->set('foo', 'bar', 30);
75 82
 		$this->assertEquals('bar', $this->driver->get('foo'));
76 83
 	}
84
+
85
+	public function testDelete(): void
86
+	{
87
+		$this->driver->set('a1', 'b2');
88
+		$this->assertTrue($this->driver->exists('a1'));
89
+
90
+		$this->assertTrue($this->driver->delete('a1'));
91
+
92
+		$this->assertFalse($this->driver->exists('a1'));
93
+	}
94
+
95
+	public function testDeleteMultiple(): void
96
+	{
97
+		$this->driver->set('a', 1);
98
+		$this->driver->set('b', 2);
99
+
100
+		$this->assertTrue($this->driver->exists('a'));
101
+		$this->assertTrue($this->driver->exists('b'));
102
+
103
+		/*$this->assertTrue(*/$this->driver->deleteMultiple(['a', 'b']);//);
104
+
105
+		$this->assertFalse($this->driver->exists('a'));
106
+		$this->assertFalse($this->driver->exists('b'));
107
+	}
108
+
109
+	public function testExpiresAt(): void
110
+	{
111
+		$this->driver->set('abc', 'def');
112
+		$result = $this->driver->expiresAt('abc', 30);
113
+		$this->assertTrue($result);
114
+	}
115
+
116
+	public function testExpiresAtBadKey(): void
117
+	{
118
+		$result = $this->driver->expiresAt('q', 30);
119
+		$this->assertFalse($result);
120
+	}
77 121
 }

+ 0
- 39
tests/Driver/MemcacheDriverTest.php View File

@@ -1,39 +0,0 @@
1
-<?php declare(strict_types=1);
2
-/**
3
- * Banker
4
- *
5
- * A Caching library implementing psr/cache
6
- *
7
- * PHP version 7.0
8
- *
9
- * @package     Banker
10
- * @author      Timothy J. Warren <tim@timshomepage.net>
11
- * @copyright   2016 - 2017  Timothy J. Warren
12
- * @license     http://www.opensource.org/licenses/mit-license.html  MIT License
13
- * @version     1.0.1
14
- * @link        https://git.timshomepage.net/timw4mail/banker
15
- */
16
-namespace Aviat\Banker\Tests\Driver;
17
-
18
-use Aviat\Banker\Driver\MemcacheDriver;
19
-use Aviat\Banker\Exception\CacheException;
20
-
21
-class MemcacheDriverTest extends DriverTestBase {
22
-
23
-	public function setup()
24
-	{
25
-		try 
26
-		{
27
-			$this->driver = new MemcacheDriver([
28
-				'host' => 'localhost',
29
-				'port' => '11211',
30
-				'persistent' => false,
31
-			]);
32
-			$this->driver->flush();
33
-		}
34
-		catch (CacheException $e)
35
-		{
36
-			$this->markTestSkipped();
37
-		}
38
-	}
39
-}

+ 1
- 0
tests/ItemTest.php View File

@@ -76,6 +76,7 @@ class ItemTest extends TestCase {
76 76
 
77 77
 		$interval2 = 500;
78 78
 		$this->item->expiresAfter($interval2);
79
+		$this->item->save();
79 80
 		$friend2 = new Friend($this->item);
80 81
 		$this->assertEquals($interval2, $friend2->ttl);
81 82
 	}

+ 123
- 90
tests/PoolTest.php View File

@@ -23,9 +23,9 @@ use PHPUnit\Framework\TestCase;
23 23
 use Psr\Log\{LoggerInterface, NullLogger};
24 24
 
25 25
 class PoolTest extends TestCase {
26
-	
26
+
27 27
 	protected $pool;
28
-	
28
+
29 29
 	public function setUp()
30 30
 	{
31 31
 		$this->pool = new Pool([
@@ -33,141 +33,176 @@ class PoolTest extends TestCase {
33 33
 			'connection' => []
34 34
 		]);
35 35
 	}
36
-	
37
-	public function testGetDefaultLogger()
36
+
37
+	public function testGetDefaultLogger(): void
38 38
 	{
39 39
 		$friend = new Friend($this->pool);
40 40
 		$driverFriend = new Friend($friend->driver);
41
-		
41
+
42 42
 		// Check that a valid logger is set
43 43
 		$this->assertInstanceOf(LoggerInterface::class, $friend->getLogger(), "Logger exists after being set");
44 44
 		$this->assertInstanceOf(LoggerInterface::class, $driverFriend->getLogger(), "Logger exists on driver after being set");
45
-		
45
+
46 46
 		// Make sure we get the default Null logger
47 47
 		$this->assertTrue(is_a($friend->getLogger(), NullLogger::class));
48 48
 		$this->assertTrue(is_a($driverFriend->getLogger(), NullLogger::class));
49 49
 	}
50
-	
51
-	public function testSetLoggerInConstructor()
50
+
51
+	public function testSetLoggerInConstructor(): void
52 52
 	{
53 53
 		$logger = new Logger('test');
54 54
 		$logger->pushHandler(new SyslogHandler(Logger::WARNING));
55
-		
55
+
56 56
 		$pool = new Pool([
57 57
 			'driver' => 'null',
58 58
 			'connection' => [],
59 59
 		], $logger);
60
-		
60
+
61 61
 		$friend = new Friend($pool);
62 62
 		$driverFriend = new Friend($friend->driver);
63
-		
63
+
64 64
 		// Check that a valid logger is set
65 65
 		$this->assertInstanceOf(LoggerInterface::class, $friend->getLogger(), "Logger exists after being set");
66 66
 		$this->assertInstanceOf(LoggerInterface::class, $driverFriend->getLogger(), "Logger exists on driver after being set");
67
-		
67
+
68 68
 		// Make sure we aren't just getting the default Null logger
69 69
 		$this->assertFalse(is_a($friend->getLogger(), NullLogger::class));
70 70
 		$this->assertFalse(is_a($driverFriend->getLogger(), NullLogger::class));
71 71
 	}
72
-	
73
-	public function testGetSetLogger()
72
+
73
+	public function testGetSetLogger(): void
74 74
 	{
75 75
 		$logger = new Logger('test');
76 76
 		$logger->pushHandler(new SyslogHandler(Logger::WARNING));
77
-		
77
+
78 78
 		$this->pool->setLogger($logger);
79
-		
79
+
80 80
 		$friend = new Friend($this->pool);
81 81
 		$driverFriend = new Friend($friend->driver);
82
-		
82
+
83 83
 		// Check that a valid logger is set
84 84
 		$this->assertInstanceOf(LoggerInterface::class, $friend->getLogger(), "Logger exists after being set");
85 85
 		$this->assertInstanceOf(LoggerInterface::class, $driverFriend->getLogger(), "Logger exists on driver after being set");
86
-		
86
+
87 87
 		// Make sure we aren't just getting the default Null logger
88 88
 		$this->assertFalse(is_a($friend->getLogger(), NullLogger::class));
89 89
 		$this->assertFalse(is_a($driverFriend->getLogger(), NullLogger::class));
90 90
 	}
91 91
 
92
-	public function testGetItem()
92
+	public function testGetItem(): void
93 93
 	{
94 94
 		$item = $this->pool->getItem('foo');
95 95
 		$this->assertInstanceOf(Item::class, $item);
96 96
 	}
97
-	
98
-	public function testItemBadKey()
97
+
98
+	public function testItemBadKey(): void
99 99
 	{
100 100
 		$this->expectException(InvalidArgumentException::class);
101
-		$this->expectExceptionMessage("Cache key must be a string.");
102
-		
101
+		$this->expectExceptionMessage('Cache key must be a string.');
102
+
103 103
 		$this->pool->getItem([]);
104 104
 	}
105
-	
106
-	public function testGetItems()
105
+
106
+	public function testGetItemsBadKey(): void
107
+	{
108
+		$this->expectException(InvalidArgumentException::class);
109
+		$this->pool->getItems([1,3,2]);
110
+	}
111
+
112
+	public function testGetItems(): void
107 113
 	{
108 114
 		$collection = $this->pool->getItems(['foo', 'bar', 'baz']);
109 115
 		$this->assertInstanceOf(ItemCollection::class, $collection);
110
-		
116
+
111 117
 		foreach($collection as $item)
112 118
 		{
113 119
 			$this->assertInstanceOf(Item::class, $item);
114 120
 		}
115 121
 	}
116
-	
117
-	public function testEmptyGetItems()
122
+
123
+	public function testGetItemsDeferredItems(): void
124
+	{
125
+		$this->pool->clear();
126
+
127
+		$deferredValues = ['x' => 1, 'y' => 2, 'z' => 3];
128
+		$keys = ['x', 'y', 'z'];
129
+
130
+		foreach ($deferredValues as $key => $value)
131
+		{
132
+			$item = $this->pool->getItem($key)->set($value);
133
+			$this->pool->saveDeferred($item);
134
+		}
135
+
136
+		$collection = $this->pool->getItems($keys);
137
+
138
+		foreach($collection as $key => $item)
139
+		{
140
+			$this->assertSame($deferredValues[$key], $item->get());
141
+		}
142
+
143
+		$this->assertCount(3, $collection);
144
+	}
145
+
146
+	public function testEmptyGetItems(): void
118 147
 	{
148
+		$this->pool->clear();
149
+
119 150
 		$collection = $this->pool->getItems();
120
-		
151
+
121 152
 		$this->assertInstanceOf(ItemCollection::class, $collection);
122
-		$this->assertEquals(0, count($collection));
153
+		$this->assertCount(0, $collection);
123 154
 	}
124
-	
125
-	public function testHasItem()
155
+
156
+	public function testHasItem(): void
126 157
 	{
158
+		$this->pool->clear();
159
+
127 160
 		// The key doesn't exist yet
128 161
 		$this->assertFalse($this->pool->hasItem('foobar'));
129
-		
162
+
130 163
 		// Create the item
131 164
 		$item = $this->pool->getItem('foobar')
132 165
 			->set('baz')
133 166
 			->save();
134
-		
167
+
135 168
 		// The item exists now
136 169
 		$this->assertTrue($this->pool->hasItem('foobar'));
137 170
 	}
138
-	
139
-	public function testHasItemBadKey()
171
+
172
+	public function testHasItemBadKey(): void
140 173
 	{
174
+		$this->pool->clear();
175
+
141 176
 		$this->expectException(InvalidArgumentException::class);
142
-		$this->expectExceptionMessage("Cache key must be a string.");
143
-		
177
+		$this->expectExceptionMessage('Cache key must be a string.');
178
+
144 179
 		$this->pool->hasItem(34);
145 180
 	}
146
-	
147
-	public function testClear()
181
+
182
+	public function testClear(): void
148 183
 	{
149 184
 		// Call clear to make sure we are working from a clean slate to start
150 185
 		$this->pool->clear();
151
-		
186
+
152 187
 		$data = [
153 188
 			'foo' => 'bar',
154 189
 			'bar' => 'baz',
155 190
 			'foobar' => 'foobarbaz'
156 191
 		];
157
-		
192
+
158 193
 		// Set up some data
159 194
 		$this->setupDataInCache($data);
160
-		
195
+
161 196
 		foreach($data as $key => $val)
162 197
 		{
163 198
 			$this->assertTrue($this->pool->hasItem($key));
164 199
 			$item = $this->pool->getItem($key);
165 200
 			$this->assertEquals($val, $item->get());
166 201
 		}
167
-		
202
+
168 203
 		// Now we clear it all!
169 204
 		$this->pool->clear();
170
-		
205
+
171 206
 		foreach($data as $key => $val)
172 207
 		{
173 208
 			$this->assertFalse($this->pool->hasItem($key));
@@ -175,41 +210,41 @@ class PoolTest extends TestCase {
175 210
 			$this->assertNull($item->get());
176 211
 		}
177 212
 	}
178
-	
179
-	public function testDeleteItemBadKey()
213
+
214
+	public function testDeleteItemBadKey(): void
180 215
 	{
181 216
 		$this->expectException(InvalidArgumentException::class);
182 217
 		$this->expectExceptionMessage("Cache key must be a string.");
183
-		
218
+
184 219
 		$this->pool->deleteItem(34);
185 220
 	}
186
-	
187
-	public function testDeleteItemThatDoesNotExist()
221
+
222
+	public function testDeleteItemThatDoesNotExist(): void
188 223
 	{
189 224
 		$this->pool->clear();
190 225
 		$this->assertFalse($this->pool->deleteItem('foo'));
191 226
 	}
192
-	
193
-	public function testDeleteItem()
227
+
228
+	public function testDeleteItem(): void
194 229
 	{
195 230
 		// Start with a clean slate
196 231
 		$this->pool->clear();
197
-		
232
+
198 233
 		$data = [
199 234
 			'foo' => 'bar',
200 235
 			'bar' => 'baz',
201 236
 			'foobar' => 'foobarbaz'
202 237
 		];
203
-		
238
+
204 239
 		$this->setupDataInCache($data);
205
-		
240
+
206 241
 		$this->pool->deleteItem('foo');
207
-		
242
+
208 243
 		// The item no longer exists
209 244
 		$this->assertFalse($this->pool->hasItem('foo'));
210 245
 		$item = $this->pool->getItem('foo');
211 246
 		$this->assertNull($item->get());
212
-		
247
+
213 248
 		// The other items still exist
214 249
 		foreach(['bar', 'foobar'] as $key)
215 250
 		{
@@ -218,21 +253,21 @@ class PoolTest extends TestCase {
218 253
 			$this->assertFalse(is_null($item->get()));
219 254
 		}
220 255
 	}
221
-	
222
-	public function testDeleteItems()
256
+
257
+	public function testDeleteItems(): void
223 258
 	{
224 259
 		$this->pool->clear();
225
-		
260
+
226 261
 		$data = [
227 262
 			'foo' => 'bar',
228 263
 			'bar' => 'baz',
229 264
 			'foobar' => 'foobarbaz'
230 265
 		];
231
-		
266
+
232 267
 		$this->setupDataInCache($data);
233
-		
268
+
234 269
 		$this->pool->deleteItems(['foo', 'bar']);
235
-		
270
+
236 271
 		foreach(['foo', 'bar'] as $key)
237 272
 		{
238 273
 			$this->assertFalse($this->pool->hasItem($key));
@@ -240,58 +275,56 @@ class PoolTest extends TestCase {
240 275
 			$this->assertNull($item->get());
241 276
 		}
242 277
 	}
243
-	
244
-	public function testSaveDeferred()
278
+
279
+	public function testSaveDeferred(): void
245 280
 	{
246 281
 		$this->pool->clear();
247
-		
282
+
248 283
 		$data = [
249 284
 			'foo' => 'bar',
250 285
 			'bar' => 'baz',
251 286
 			'foobar' => 'foobarbaz'
252 287
 		];
253
-		
288
+
254 289
 		$this->setupDeferredData($data);
255
-		
290
+
256 291
 		// See that the data is returned by the pool
257 292
 		foreach($data as $key => $val)
258 293
 		{
259 294
 			$this->assertTrue($this->pool->hasItem($key));
260 295
 			$item = $this->pool->getItem($key);
261
-			
262
-			// The cache hasn't been updated yet, even
263
-			// though the pool data has
264
-			$this->assertNotEquals($data[$key], $item->get());
296
+
297
+			// Since the value has been deferred,
298
+			// the pool will return the updated value,
299
+			// even though the cache hasn't been updated yet
300
+			$this->assertEquals($data[$key], $item->get());
265 301
 		}
266 302
 	}
267
-	
268
-	public function testCommit()
303
+
304
+	public function testCommit(): void
269 305
 	{
270 306
 		$this->pool->clear();
271
-		
307
+
272 308
 		// If there are no deferred items, this will return true
273 309
 		$this->assertTrue($this->pool->commit());
274
-		
310
+
275 311
 		$data = [
276 312
 			'foo' => 'bar',
277 313
 			'bar' => 'baz',
278 314
 			'foobar' => 'foobarbaz'
279 315
 		];
280
-		
316
+
281 317
 		$this->setupDeferredData($data);
282
-		
318
+
283 319
 		// See that the data is returned by the pool
284 320
 		foreach($this->pool->getItems(array_keys($data)) as $key => $item)
285 321
 		{
286 322
 			$this->assertTrue($this->pool->hasItem($key));
287
-			
288
-			// The cache hasn't been updated yet, even
289
-			// though the pool data has
290
-			$this->assertNotEquals($data[$key], $item->get());
323
+			$this->assertEquals($data[$key], $item->get());
291 324
 		}
292
-		
325
+
293 326
 		$this->pool->commit();
294
-		
327
+
295 328
 		// See that the data is saved in the cache backend
296 329
 		foreach($this->pool->getItems(array_keys($data)) as $key => $item)
297 330
 		{
@@ -299,25 +332,25 @@ class PoolTest extends TestCase {
299 332
 			$this->assertEquals($data[$key], $item->get());
300 333
 		}
301 334
 	}
302
-	
303
-	protected function setupDeferredData($data)
335
+
336
+	protected function setupDeferredData($data): void
304 337
 	{
305 338
 		foreach($data as $key => $val)
306 339
 		{
307 340
 			$item = $this->pool->getItem($key)
308 341
 				->set($val);
309
-				
342
+
310 343
 			$this->assertTrue($this->pool->saveDeferred($item));
311 344
 		}
312 345
 	}
313
-	
314
-	protected function setupDataInCache($data)
346
+
347
+	protected function setupDataInCache($data): void
315 348
 	{
316 349
 		foreach($data as $key => $val)
317 350
 		{
318 351
 			$item = $this->pool->getItem($key)
319 352
 				->set($val);
320
-				
353
+
321 354
 			$this->pool->save($item);
322 355
 		}
323 356
 	}