diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index fe8cb52..558fb5a 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -97,6 +97,21 @@ jobs: runs-on: ubuntu-latest timeout-minutes: 15 + services: + memcached: + image: memcached:1.6-alpine + ports: + - 11211:11211 + redis: + image: redis:8-alpine + ports: + - 6379:6379 + options: >- + --health-cmd "redis-cli ping" + --health-interval 10s + --health-timeout 5s + --health-retries 5 + steps: - name: Check out repository uses: actions/checkout@v6 @@ -105,7 +120,7 @@ jobs: uses: shivammathur/setup-php@v2 with: php-version: '8.3' - coverage: none + coverage: xdebug extensions: apcu, igbinary, memcache, memcached, opcache, redis tools: composer:v2 @@ -118,12 +133,36 @@ jobs: ${{ runner.os }}-php-8.3-composer- ${{ runner.os }}-composer- + - name: Wait for services + run: | + for port in 11211 6379; do + for attempt in {1..30}; do + if (echo > /dev/tcp/127.0.0.1/${port}) >/dev/null 2>&1; then + break + fi + + if [ "${attempt}" -eq 30 ]; then + echo "Service on port ${port} did not become ready in time." + exit 1 + fi + + sleep 1 + done + done + - name: Install analysis dependencies - run: > - composer require --dev --no-interaction --prefer-dist - phpstan/phpstan:^1.12 - "predis/predis:^1.1 || ^2.0 || ^3.0" - "symfony/var-exporter:^5.4 || ^6.0 || ^7.0" + run: | + composer config --no-plugins allow-plugins.infection/extension-installer true + composer require --dev --no-interaction --prefer-dist \ + infection/infection:^0.32.7 \ + phpstan/phpstan:^1.12.27 \ + "predis/predis:^1.1 || ^2.0 || ^3.0" \ + "symfony/var-exporter:^5.4 || ^6.0 || ^7.0" - name: Run PHPStan run: php vendor/bin/phpstan analyse + + - name: Run Infection + env: + XDEBUG_MODE: coverage + run: php vendor/bin/infection --show-mutations=0 diff --git a/infection.json.dist b/infection.json.dist new file mode 100644 index 0000000..c16ea22 --- /dev/null +++ b/infection.json.dist @@ -0,0 +1,20 @@ +{ + "$schema": "https://infection.github.io/schema.json", + "source": { + "directories": [ + "src" + ] + }, + "timeout": 10, + "threads": "max", + "phpUnit": { + "configDir": ".", + "customPath": "vendor/bin/phpunit" + }, + "phpStan": { + "configDir": ".", + "customPath": "vendor/bin/phpstan" + }, + "testFramework": "phpunit", + "staticAnalysisTool": "phpstan" +} diff --git a/phpunit.xml b/phpunit.xml index 4b632cc..b95ef36 100644 --- a/phpunit.xml +++ b/phpunit.xml @@ -1,11 +1,13 @@ prop = 'prop data'; + $ao['prop'] = 'prop data'; $ao['arr'] = 'array data'; $return = $this->cache->setItem('ao', $ao); @@ -74,9 +74,9 @@ public function testGetItem() $return = $this->cache->getItem('ao'); - $ao = new ArrayObject(); + $ao = new ArrayObject([], ArrayObject::ARRAY_AS_PROPS); - $ao->prop = 'prop data'; + $ao['prop'] = 'prop data'; $ao['arr'] = 'array data'; static::assertSame($ao->prop, $return->prop); @@ -120,11 +120,14 @@ public function testGetStaticValues() assert($this->cache->getAdapter() instanceof AdapterArray); $values = $this->cache->getAdapter()->getStaticValues(); + $expectedAo = new ArrayObject([], ArrayObject::ARRAY_AS_PROPS); + $expectedAo['prop'] = 'prop data'; + $expectedAo['arr'] = 'array data'; // User-set values are present with the expected serialized content. static::assertSame('N;', $values['foo_null']); static::assertSame('a:3:{i:0;i:3;i:1;i:2;i:2;i:1;}', $values['foo']); - static::assertSame('O:11:"ArrayObject":4:{i:0;i:0;i:1;a:1:{s:3:"arr";s:10:"array data";}i:2;a:1:{s:4:"prop";s:9:"prop data";}i:3;N;}', $values['ao']); + static::assertSame(\serialize($expectedAo), $values['ao']); static::assertSame('a:3:{i:0;i:3;i:1;i:2;i:2;i:1;}', $values['barfoo']); // The adapter also holds key-registry entries (one per prefix used so far). diff --git a/tests/CacheAutoInitOverwriteTest.php b/tests/CacheAutoInitOverwriteTest.php index c9ee31b..5ffe90e 100644 --- a/tests/CacheAutoInitOverwriteTest.php +++ b/tests/CacheAutoInitOverwriteTest.php @@ -51,19 +51,20 @@ public function testGetNotExists() public function testSet() { $key = 'some:test:key'; - $value = \uniqid(\time(), true); + $value = \uniqid('', true); $result = $this->cache->setItem($key, $value, 10); static::assertTrue($result); } - /** - * @depends testSet - */ public function testKeyAfterSet() { - $item = $this->cache->getItem('some:test:key'); + $key = 'some:test:key'; + + $this->cache->setItem($key, \uniqid('', true), 10); + + $item = $this->cache->getItem($key); static::assertNotNull($item); } @@ -71,7 +72,7 @@ public function testKeyAfterSet() public function testSetWithTtl() { $key = 'some:test:key'; - $value = \uniqid(\time(), true); + $value = \uniqid('', true); $ttl = \random_int(20, 5000); $result = $this->cache->setItem($key, $value, $ttl); @@ -82,7 +83,7 @@ public function testSetWithTtl() public function testSetToDate() { $key = 'some:test:key'; - $value = \uniqid(\time(), true); + $value = \uniqid('', true); $date = (new DateTime('now'))->add(new DateInterval('PT1H')); $result = $this->cache->setItemToDate($key, $value, $date); @@ -95,7 +96,7 @@ public function testSetWrongDate() $this->expectException(\voku\cache\Exception\InvalidArgumentException::class); $key = 'some:test:key'; - $value = \uniqid(\time(), true); + $value = \uniqid('', true); $date = new DateTime(); $date->sub(new DateInterval('PT1H')); @@ -106,18 +107,20 @@ public function testRemove() { $key = 'some:test:key'; + $this->cache->setItem($key, \uniqid('', true), 10); + $result = $this->cache->removeItem($key); static::assertTrue($result); } - /** - * @depends testRemove - */ public function testExists() { $key = 'some:test:key'; + $this->cache->setItem($key, \uniqid('', true), 10); + $this->cache->removeItem($key); + $result = $this->cache->existsItem($key); static::assertFalse($result); @@ -155,7 +158,6 @@ static function () { true ); - // reset default prefix - $this->cache->setPrefix(''); + $this->cache->setPrefix(static::class . ':' . $this->getName(false) . ':'); } } diff --git a/tests/CacheAutoInitReplaceTest.php b/tests/CacheAutoInitReplaceTest.php index 267dc14..7f22c05 100644 --- a/tests/CacheAutoInitReplaceTest.php +++ b/tests/CacheAutoInitReplaceTest.php @@ -51,19 +51,20 @@ public function testGetNotExists() public function testSet() { $key = 'some:test:key'; - $value = \uniqid(\time(), true); + $value = \uniqid('', true); $result = $this->cache->setItem($key, $value, 10); static::assertTrue($result); } - /** - * @depends testSet - */ public function testKeyAfterSet() { - $item = $this->cache->getItem('some:test:key'); + $key = 'some:test:key'; + + $this->cache->setItem($key, \uniqid('', true), 10); + + $item = $this->cache->getItem($key); static::assertNotNull($item); } @@ -71,7 +72,7 @@ public function testKeyAfterSet() public function testSetWithTtl() { $key = 'some:test:key'; - $value = \uniqid(\time(), true); + $value = \uniqid('', true); $ttl = \random_int(20, 5000); $result = $this->cache->setItem($key, $value, $ttl); @@ -82,7 +83,7 @@ public function testSetWithTtl() public function testSetToDate() { $key = 'some:test:key'; - $value = \uniqid(\time(), true); + $value = \uniqid('', true); $date = (new DateTime('now'))->add(new DateInterval('PT1H')); $result = $this->cache->setItemToDate($key, $value, $date); @@ -95,7 +96,7 @@ public function testSetWrongDate() $this->expectException(\voku\cache\Exception\InvalidArgumentException::class); $key = 'some:test:key'; - $value = \uniqid(\time(), true); + $value = \uniqid('', true); $date = new DateTime(); $date->sub(new DateInterval('PT1H')); @@ -106,18 +107,20 @@ public function testRemove() { $key = 'some:test:key'; + $this->cache->setItem($key, \uniqid('', true), 10); + $result = $this->cache->removeItem($key); static::assertTrue($result); } - /** - * @depends testRemove - */ public function testExists() { $key = 'some:test:key'; + $this->cache->setItem($key, \uniqid('', true), 10); + $this->cache->removeItem($key); + $result = $this->cache->existsItem($key); static::assertFalse($result); @@ -151,7 +154,6 @@ static function () { false ); - // reset default $memcachedprefix - $this->cache->setPrefix(''); + $this->cache->setPrefix(static::class . ':' . $this->getName(false) . ':'); } } diff --git a/tests/CacheAutoInitTest.php b/tests/CacheAutoInitTest.php index ae90e71..816e070 100644 --- a/tests/CacheAutoInitTest.php +++ b/tests/CacheAutoInitTest.php @@ -53,19 +53,20 @@ public function testGetNotExists() public function testSet() { $key = 'some:test:key'; - $value = \uniqid(\time(), true); + $value = \uniqid('', true); $result = $this->cache->setItem($key, $value, 10); static::assertTrue($result); } - /** - * @depends testSet - */ public function testKeyAfterSet() { - $item = $this->cache->getItem('some:test:key'); + $key = 'some:test:key'; + + $this->cache->setItem($key, \uniqid('', true), 10); + + $item = $this->cache->getItem($key); static::assertNotNull($item); } @@ -73,7 +74,7 @@ public function testKeyAfterSet() public function testSetWithTtl() { $key = 'some:test:key'; - $value = \uniqid(\time(), true); + $value = \uniqid('', true); $ttl = \random_int(20, 5000); $result = $this->cache->setItem($key, $value, $ttl); @@ -84,7 +85,7 @@ public function testSetWithTtl() public function testSetToDate() { $key = 'some:test:key'; - $value = \uniqid(\time(), true); + $value = \uniqid('', true); $date = (new DateTime('now'))->add(new DateInterval('PT1H')); $result = $this->cache->setItemToDate($key, $value, $date); @@ -97,7 +98,7 @@ public function testSetWrongDate() $this->expectException(\voku\cache\Exception\InvalidArgumentException::class); $key = 'some:test:key'; - $value = \uniqid(\time(), true); + $value = \uniqid('', true); $date = new DateTime(); $date->sub(new DateInterval('PT1H')); @@ -108,18 +109,20 @@ public function testRemove() { $key = 'some:test:key'; + $this->cache->setItem($key, \uniqid('', true), 10); + $result = $this->cache->removeItem($key); static::assertTrue($result); } - /** - * @depends testRemove - */ public function testExists() { $key = 'some:test:key'; + $this->cache->setItem($key, \uniqid('', true), 10); + $this->cache->removeItem($key); + $result = $this->cache->existsItem($key); static::assertFalse($result); @@ -132,7 +135,6 @@ protected function setUpThanksForNothing() { $this->cache = new Cache(null, null, false, true); - // reset default prefix - $this->cache->setPrefix(''); + $this->cache->setPrefix(static::class . ':' . $this->getName(false) . ':'); } }