Duplicate code is one of the most pungent code smells. A rule that is often used is to re-structure code once it is duplicated in three or more places.
Common duplication problems, and corresponding solutions are:
| 1 | <?php |
||
| 17 | class FileTest extends \PHPUnit_Framework_TestCase |
||
| 18 | { |
||
| 19 | /** |
||
| 20 | * @var Cache\File |
||
| 21 | * @since 1.0 |
||
| 22 | */ |
||
| 23 | private $instance; |
||
| 24 | |||
| 25 | /** |
||
| 26 | * Tests the Joomla\Cache\File::__construct method. |
||
| 27 | * |
||
| 28 | * @return void |
||
| 29 | * |
||
| 30 | * @covers Joomla\Cache\File::__construct |
||
| 31 | * @since 1.1.3 |
||
| 32 | * @expectedException \RuntimeException |
||
| 33 | */ |
||
| 34 | public function test__construct() |
||
| 35 | { |
||
| 36 | $options = array( |
||
| 37 | 'file.path' => '/' |
||
| 38 | ); |
||
| 39 | |||
| 40 | $this->instance = new Cache\File($options); |
||
| 41 | } |
||
| 42 | |||
| 43 | /** |
||
| 44 | * Tests for the correct Psr\Cache return values. |
||
| 45 | * |
||
| 46 | * @return void |
||
| 47 | * |
||
| 48 | * @coversNothing |
||
| 49 | * @since 1.0 |
||
| 50 | */ |
||
| 51 | public function testPsrCache() |
||
| 52 | { |
||
| 53 | $this->assertInternalType('boolean', $this->instance->clear(), 'Checking clear.'); |
||
| 54 | $this->assertInstanceOf('\Psr\Cache\CacheItemInterface', $this->instance->getItem('foo'), 'Checking get.'); |
||
| 55 | $this->assertInternalType('array', $this->instance->getItems(array('foo')), 'Checking getMultiple.'); |
||
| 56 | $this->assertInternalType('boolean', $this->instance->deleteItem('foo'), 'Checking remove.'); |
||
| 57 | $this->assertInternalType('array', $this->instance->deleteItems(array('foo')), 'Checking removeMultiple.'); |
||
| 58 | |||
| 59 | // Create a stub for the CacheItemInterface class. |
||
| 60 | $stub = $this->getMockBuilder('\\Psr\\Cache\\CacheItemInterface') |
||
| 61 | ->getMock(); |
||
| 62 | |||
| 63 | $stub->method('get') |
||
| 64 | ->willReturn('bar'); |
||
| 65 | |||
| 66 | $stub->method('getKey') |
||
| 67 | ->willReturn('foo'); |
||
| 68 | |||
| 69 | $this->assertInternalType('boolean', $this->instance->save($stub), 'Checking set.'); |
||
| 70 | } |
||
| 71 | |||
| 72 | /** |
||
| 73 | * Tests constructor when given non writable cache folder |
||
| 74 | * |
||
| 75 | * @return void |
||
| 76 | * |
||
| 77 | * @covers Joomla\Cache\File::__construct |
||
| 78 | * @since 1.1.4 |
||
| 79 | * @expectedException \RuntimeException |
||
| 80 | */ |
||
| 81 | public function test__construct_exception() |
||
| 82 | { |
||
| 83 | $options = array( |
||
| 84 | 'file.path' => __DIR__ . '/no_write_tmp' |
||
| 85 | ); |
||
| 86 | |||
| 87 | mkdir($options['file.path']); |
||
| 88 | chmod($options['file.path'], 0000); |
||
| 89 | |||
| 90 | new Cache\File($options); |
||
| 91 | } |
||
| 92 | |||
| 93 | /** |
||
| 94 | * Tests the Joomla\Cache\File::clear method. |
||
| 95 | * |
||
| 96 | * @return void |
||
| 97 | * |
||
| 98 | * @covers Joomla\Cache\File::clear |
||
| 99 | * @since 1.0 |
||
| 100 | */ |
||
| 101 | public function testClear() |
||
| 102 | { |
||
| 103 | // Create a stub for the CacheItemInterface class. |
||
| 104 | $stub = $this->getMockBuilder('\\Psr\\Cache\\CacheItemInterface') |
||
| 105 | ->getMock(); |
||
| 106 | |||
| 107 | $stub->method('get') |
||
| 108 | ->willReturn('bar'); |
||
| 109 | |||
| 110 | $stub->method('getKey') |
||
| 111 | ->willReturn('foo'); |
||
| 112 | |||
| 113 | $this->instance->save($stub); |
||
| 114 | |||
| 115 | // Create a stub for the CacheItemInterface class. |
||
| 116 | $stub2 = $this->getMockBuilder('\\Psr\\Cache\\CacheItemInterface') |
||
| 117 | ->getMock(); |
||
| 118 | |||
| 119 | $stub2->method('get') |
||
| 120 | ->willReturn('car'); |
||
| 121 | |||
| 122 | $stub2->method('getKey') |
||
| 123 | ->willReturn('goo'); |
||
| 124 | |||
| 125 | $this->instance->save($stub2); |
||
| 126 | |||
| 127 | $this->instance->clear(); |
||
| 128 | |||
| 129 | $this->assertFalse($this->instance->getItem('foo')->isHit()); |
||
| 130 | $this->assertFalse($this->instance->getItem('goo')->isHit()); |
||
| 131 | } |
||
| 132 | |||
| 133 | /** |
||
| 134 | * Tests the Joomla\Cache\File::get method. |
||
| 135 | * |
||
| 136 | * @return void |
||
| 137 | * |
||
| 138 | * @covers Joomla\Cache\File::get |
||
| 139 | * @since 1.0 |
||
| 140 | */ |
||
| 141 | public function testGet() |
||
| 142 | { |
||
| 143 | $this->assertFalse($this->instance->getItem('foo')->isHit(), 'Checks an unknown key.'); |
||
| 144 | |||
| 145 | // Create a stub for the CacheItemInterface class. |
||
| 146 | $stub = $this->getMockBuilder('\\Joomla\\Cache\\Item\\AbstractItem') |
||
| 147 | ->getMock(); |
||
| 148 | |||
| 149 | $stub->method('get') |
||
| 150 | ->willReturn('bar'); |
||
| 151 | |||
| 152 | $stub->method('getKey') |
||
| 153 | ->willReturn('foo'); |
||
| 154 | |||
| 155 | $expireDate = new \DateTime; |
||
| 156 | $expireDate->setTimestamp(time()); |
||
| 157 | $stub->method('getExpiration') |
||
| 158 | ->willReturn($expireDate); |
||
| 159 | |||
| 160 | $this->instance->save($stub); |
||
| 161 | |||
| 162 | $this->assertEquals( |
||
| 163 | 'bar', |
||
| 164 | $this->instance->getItem('foo')->get(), |
||
| 165 | 'The key should have not been deleted.' |
||
| 166 | ); |
||
| 167 | |||
| 168 | sleep(1); |
||
| 169 | |||
| 170 | $this->assertFalse( |
||
| 171 | $this->instance->getItem('foo')->isHit(), |
||
| 172 | 'The key should have been deleted.' |
||
| 173 | ); |
||
| 174 | } |
||
| 175 | |||
| 176 | /** |
||
| 177 | * Tests the Joomla\Cache\File::hasItem method. |
||
| 178 | * |
||
| 179 | * @return void |
||
| 180 | * |
||
| 181 | * @covers Joomla\Cache\File::hasItem |
||
| 182 | * @since 1.0 |
||
| 183 | */ |
||
| 184 | public function testHasItem() |
||
| 185 | { |
||
| 186 | $this->assertFalse($this->instance->hasItem('foo')); |
||
| 187 | |||
| 188 | // Create a stub for the CacheItemInterface class. |
||
| 189 | $stub = $this->getMockBuilder('\\Psr\\Cache\\CacheItemInterface') |
||
| 190 | ->getMock(); |
||
| 191 | |||
| 192 | $stub->method('get') |
||
| 193 | ->willReturn('bar'); |
||
| 194 | |||
| 195 | $stub->method('getKey') |
||
| 196 | ->willReturn('foo'); |
||
| 197 | |||
| 198 | $this->instance->save($stub); |
||
| 199 | $this->assertTrue($this->instance->hasItem('foo')); |
||
| 200 | } |
||
| 201 | |||
| 202 | /** |
||
| 203 | * Tests the Joomla\Cache\File::deleteItem method. |
||
| 204 | * |
||
| 205 | * @return void |
||
| 206 | * |
||
| 207 | * @covers Joomla\Cache\File::deleteItem |
||
| 208 | * @since 1.0 |
||
| 209 | */ |
||
| 210 | public function testDeleteItem() |
||
| 211 | { |
||
| 212 | // Create a stub for the CacheItemInterface class. |
||
| 213 | $stub = $this->getMockBuilder('\\Psr\\Cache\\CacheItemInterface') |
||
| 214 | ->getMock(); |
||
| 215 | |||
| 216 | $stub->method('get') |
||
| 217 | ->willReturn('bar'); |
||
| 218 | |||
| 219 | $stub->method('getKey') |
||
| 220 | ->willReturn('foo'); |
||
| 221 | |||
| 222 | $this->assertTrue( |
||
| 223 | $this->instance->save($stub), |
||
| 224 | 'Checks the value was set' |
||
| 225 | ); |
||
| 226 | $this->assertTrue( |
||
| 227 | $this->instance->deleteItem('foo'), |
||
| 228 | 'Checks the value was removed' |
||
| 229 | ); |
||
| 230 | $this->assertNull( |
||
| 231 | $this->instance->getItem('foo')->get(), |
||
| 232 | 'Checks for the delete' |
||
| 233 | ); |
||
| 234 | } |
||
| 235 | |||
| 236 | /** |
||
| 237 | * Tests the Joomla\Cache\File::deleteItem method fail to remove |
||
| 238 | * |
||
| 239 | * @return void |
||
| 240 | * |
||
| 241 | * @covers Joomla\Cache\File::deleteItem |
||
| 242 | * @since 1.1.4 |
||
| 243 | */ |
||
| 244 | public function testDeleteItemFail() |
||
| 245 | { |
||
| 246 | // Create a stub for the CacheItemInterface class. |
||
| 247 | $stub = $this->getMockBuilder('\\Psr\\Cache\\CacheItemInterface') |
||
| 248 | ->getMock(); |
||
| 249 | |||
| 250 | $stub->method('get') |
||
| 251 | ->willReturn('barabum'); |
||
| 252 | |||
| 253 | $stub->method('getKey') |
||
| 254 | ->willReturn('foo'); |
||
| 255 | |||
| 256 | $this->assertTrue( |
||
| 257 | $this->instance->save($stub), |
||
| 258 | 'Checks the value was set' |
||
| 259 | ); |
||
| 260 | |||
| 261 | $this->assertTrue($this->instance->deleteItem('foo'), 'Checks the value was removed'); |
||
| 262 | } |
||
| 263 | |||
| 264 | /** |
||
| 265 | * Tests the Joomla\Cache\File::save method. |
||
| 266 | * |
||
| 267 | * @return void |
||
| 268 | * |
||
| 269 | * @covers Joomla\Cache\File::save |
||
| 270 | * @covers Joomla\Cache\File::getItem |
||
| 271 | * @covers Joomla\Cache\File::deleteItem |
||
| 272 | * @since 1.0 |
||
| 273 | */ |
||
| 274 | public function testSave() |
||
| 275 | { |
||
| 276 | $fileName = TestHelper::invoke($this->instance, 'fetchStreamUri', 'foo'); |
||
| 277 | |||
| 278 | $this->assertFileNotExists($fileName); |
||
| 279 | |||
| 280 | // Create a stub for the CacheItemInterface class. |
||
| 281 | $stub = $this->getMockBuilder('\\Psr\\Cache\\CacheItemInterface') |
||
| 282 | ->getMock(); |
||
| 283 | |||
| 284 | $stub->method('get') |
||
| 285 | ->willReturn('bar'); |
||
| 286 | |||
| 287 | $stub->method('getKey') |
||
| 288 | ->willReturn('foo'); |
||
| 289 | |||
| 290 | $this->instance->save($stub); |
||
| 291 | $this->assertFileExists( |
||
| 292 | $fileName, |
||
| 293 | 'Checks the cache file was created.' |
||
| 294 | ); |
||
| 295 | |||
| 296 | $this->assertEquals( |
||
| 297 | 'bar', $this->instance->getItem('foo')->get(), |
||
| 298 | 'Checks we got the cached value back.' |
||
| 299 | ); |
||
| 300 | |||
| 301 | $this->instance->deleteItem('foo'); |
||
| 302 | $this->assertNull( |
||
| 303 | $this->instance->getItem('foo')->get(), |
||
| 304 | 'Checks for the delete.' |
||
| 305 | ); |
||
| 306 | } |
||
| 307 | |||
| 308 | /** |
||
| 309 | * Tests the Joomla\Cache\File::checkFilePath method. |
||
| 310 | * |
||
| 311 | * @return void |
||
| 312 | * |
||
| 313 | * @covers Joomla\Cache\File::checkFilePath |
||
| 314 | * @since 1.0 |
||
| 315 | */ |
||
| 316 | public function testCheckFilePath() |
||
| 317 | { |
||
| 318 | $this->assertTrue(TestHelper::invoke($this->instance, 'checkFilePath', __DIR__)); |
||
| 319 | } |
||
| 320 | |||
| 321 | /** |
||
| 322 | * Tests the Joomla\Cache\File::checkFilePath method for a known exception. |
||
| 323 | * |
||
| 324 | * @return void |
||
| 325 | * |
||
| 326 | * @covers Joomla\Cache\File::checkFilePath |
||
| 327 | * @expectedException \RuntimeException |
||
| 328 | * @since 1.0 |
||
| 329 | */ |
||
| 330 | public function testCheckFilePathInvalidPath() |
||
| 331 | { |
||
| 332 | // Invalid path |
||
| 333 | TestHelper::invoke($this->instance, 'checkFilePath', 'foo123'); |
||
| 334 | } |
||
| 335 | |||
| 336 | /** |
||
| 337 | * Tests the Joomla\Cache\File::checkFilePath method for a known exception. |
||
| 338 | * |
||
| 339 | * @return void |
||
| 340 | * |
||
| 341 | * @covers Joomla\Cache\File::checkFilePath |
||
| 342 | * @expectedException \RuntimeException |
||
| 343 | * @since 1.0 |
||
| 344 | */ |
||
| 345 | public function testCheckFilePathUnwritablePath() |
||
| 346 | { |
||
| 347 | // Check for an unwritable folder. |
||
| 348 | mkdir(__DIR__ . '/tmp/~uwd', 0444); |
||
| 349 | TestHelper::invoke($this->instance, 'checkFilePath', __DIR__ . '/tmp/~uwd'); |
||
| 350 | } |
||
| 351 | |||
| 352 | /** |
||
| 353 | * Tests the Joomla\Cache\File::fetchStreamUri method. |
||
| 354 | * |
||
| 355 | * @return void |
||
| 356 | * |
||
| 357 | * @covers Joomla\Cache\File::fetchStreamUri |
||
| 358 | * @since 1.0 |
||
| 359 | */ |
||
| 360 | public function testFetchStreamUri() |
||
| 361 | { |
||
| 362 | $fileName = TestHelper::invoke($this->instance, 'fetchStreamUri', 'test'); |
||
| 363 | } |
||
| 364 | |||
| 365 | /** |
||
| 366 | * Setup the tests. |
||
| 367 | * |
||
| 368 | * @return void |
||
| 369 | * |
||
| 370 | * @since 1.0 |
||
| 371 | */ |
||
| 372 | protected function setUp() |
||
| 373 | { |
||
| 374 | parent::setUp(); |
||
| 375 | |||
| 376 | // Clean up the test folder. |
||
| 377 | $this->tearDown(); |
||
| 378 | |||
| 379 | $options = array( |
||
| 380 | 'file.path' => __DIR__ . '/tmp' |
||
| 381 | ); |
||
| 382 | |||
| 383 | $this->instance = new Cache\File($options); |
||
| 384 | } |
||
| 385 | |||
| 386 | /** |
||
| 387 | * Teardown the test. |
||
| 388 | * |
||
| 389 | * @return void |
||
| 390 | * |
||
| 391 | * @since 1.0 |
||
| 392 | */ |
||
| 393 | protected function tearDown() |
||
| 394 | { |
||
| 395 | $iterator = new \RecursiveIteratorIterator( |
||
| 396 | new \RecursiveDirectoryIterator(__DIR__ . '/tmp/'), |
||
| 397 | \RecursiveIteratorIterator::CHILD_FIRST |
||
| 398 | ); |
||
| 399 | |||
| 400 | foreach ($iterator as $file) |
||
| 401 | { |
||
| 402 | if ($file->isFile() && $file->getExtension() == 'data') |
||
| 403 | { |
||
| 404 | unlink($file->getRealPath()); |
||
| 405 | } |
||
| 406 | elseif ($file->isDir() && strpos($file->getFilename(), '~') === 0) |
||
| 407 | { |
||
| 408 | rmdir($file->getRealPath()); |
||
| 409 | } |
||
| 410 | } |
||
| 411 | |||
| 412 | if (is_dir(__DIR__ . '/no_write_tmp')) |
||
| 413 | { |
||
| 414 | rmdir(__DIR__ . '/no_write_tmp'); |
||
| 415 | } |
||
| 416 | } |
||
| 417 | } |
||
| 418 |