diff --git a/tests/framework/caching/ChainedDependencyTest.php b/tests/framework/caching/ChainedDependencyTest.php new file mode 100644 index 00000000000..30778ebf19d --- /dev/null +++ b/tests/framework/caching/ChainedDependencyTest.php @@ -0,0 +1,290 @@ +cache = new ArrayCache(); + } + + public function testDependOnAllTrueNoneChanged(): void + { + $dep1 = new CallbackDependency(['callback' => function () { + return 1; + }]); + $dep2 = new CallbackDependency(['callback' => function () { + return 2; + }]); + + $chained = new ChainedDependency([ + 'dependencies' => [$dep1, $dep2], + 'dependOnAll' => true, + ]); + + $chained->evaluateDependency($this->cache); + $this->assertFalse($chained->isChanged($this->cache)); + } + + public function testDependOnAllTrueOneChanged(): void + { + $value = 1; + $dep1 = new CallbackDependency(['callback' => function () use (&$value) { + return $value; + }]); + $dep2 = new CallbackDependency(['callback' => function () { + return 2; + }]); + + $chained = new ChainedDependency([ + 'dependencies' => [$dep1, $dep2], + 'dependOnAll' => true, + ]); + + $chained->evaluateDependency($this->cache); + $value = 99; + $this->assertTrue($chained->isChanged($this->cache)); + } + + public function testDependOnAllTrueAllChanged(): void + { + $v1 = 1; + $v2 = 2; + $dep1 = new CallbackDependency(['callback' => function () use (&$v1) { + return $v1; + }]); + $dep2 = new CallbackDependency(['callback' => function () use (&$v2) { + return $v2; + }]); + + $chained = new ChainedDependency([ + 'dependencies' => [$dep1, $dep2], + 'dependOnAll' => true, + ]); + + $chained->evaluateDependency($this->cache); + $v1 = 10; + $v2 = 20; + $this->assertTrue($chained->isChanged($this->cache)); + } + + public function testDependOnAllFalseNoneChanged(): void + { + $dep1 = new CallbackDependency(['callback' => function () { + return 1; + }]); + $dep2 = new CallbackDependency(['callback' => function () { + return 2; + }]); + + $chained = new ChainedDependency([ + 'dependencies' => [$dep1, $dep2], + 'dependOnAll' => false, + ]); + + $chained->evaluateDependency($this->cache); + $this->assertFalse($chained->isChanged($this->cache)); + } + + public function testDependOnAllFalseOneChanged(): void + { + $value = 1; + $dep1 = new CallbackDependency(['callback' => function () use (&$value) { + return $value; + }]); + $dep2 = new CallbackDependency(['callback' => function () { + return 2; + }]); + + $chained = new ChainedDependency([ + 'dependencies' => [$dep1, $dep2], + 'dependOnAll' => false, + ]); + + $chained->evaluateDependency($this->cache); + $value = 99; + $this->assertFalse($chained->isChanged($this->cache)); + } + + public function testDependOnAllFalseAllChanged(): void + { + $v1 = 1; + $v2 = 2; + $dep1 = new CallbackDependency(['callback' => function () use (&$v1) { + return $v1; + }]); + $dep2 = new CallbackDependency(['callback' => function () use (&$v2) { + return $v2; + }]); + + $chained = new ChainedDependency([ + 'dependencies' => [$dep1, $dep2], + 'dependOnAll' => false, + ]); + + $chained->evaluateDependency($this->cache); + $v1 = 10; + $v2 = 20; + $this->assertTrue($chained->isChanged($this->cache)); + } + + public function testEmptyDependenciesDependOnAllTrue(): void + { + $chained = new ChainedDependency([ + 'dependencies' => [], + 'dependOnAll' => true, + ]); + + $chained->evaluateDependency($this->cache); + $this->assertFalse($chained->isChanged($this->cache)); + } + + public function testEmptyDependenciesDependOnAllFalse(): void + { + $chained = new ChainedDependency([ + 'dependencies' => [], + 'dependOnAll' => false, + ]); + + $chained->evaluateDependency($this->cache); + $this->assertTrue($chained->isChanged($this->cache)); + } + + public function testEvaluateDependencyCallsAllSubDependencies(): void + { + $evaluated = []; + + $dep1 = new CallbackDependency(['callback' => function () use (&$evaluated) { + $evaluated[] = 'dep1'; + return 1; + }]); + $dep2 = new CallbackDependency(['callback' => function () use (&$evaluated) { + $evaluated[] = 'dep2'; + return 2; + }]); + + $chained = new ChainedDependency([ + 'dependencies' => [$dep1, $dep2], + ]); + + $chained->evaluateDependency($this->cache); + $this->assertSame(['dep1', 'dep2'], $evaluated); + } + + public function testDefaultDependOnAllIsTrue(): void + { + $chained = new ChainedDependency(); + $this->assertTrue($chained->dependOnAll); + } + + public function testDefaultDependenciesIsEmptyArray(): void + { + $chained = new ChainedDependency(); + $this->assertSame([], $chained->dependencies); + } + + public function testSingleDependencyChanged(): void + { + $value = 'a'; + $dep = new CallbackDependency(['callback' => function () use (&$value) { + return $value; + }]); + + $chained = new ChainedDependency([ + 'dependencies' => [$dep], + 'dependOnAll' => true, + ]); + + $chained->evaluateDependency($this->cache); + $this->assertFalse($chained->isChanged($this->cache)); + + $value = 'b'; + $this->assertTrue($chained->isChanged($this->cache)); + } + + public function testSingleDependencyDependOnAllFalse(): void + { + $value = 'a'; + $dep = new CallbackDependency(['callback' => function () use (&$value) { + return $value; + }]); + + $chained = new ChainedDependency([ + 'dependencies' => [$dep], + 'dependOnAll' => false, + ]); + + $chained->evaluateDependency($this->cache); + $this->assertFalse($chained->isChanged($this->cache)); + + $value = 'b'; + $this->assertTrue($chained->isChanged($this->cache)); + } + + public function testThreeDependenciesDependOnAllTrueMiddleChanged(): void + { + $v2 = 'stable'; + $dep1 = new CallbackDependency(['callback' => function () { + return 'fixed'; + }]); + $dep2 = new CallbackDependency(['callback' => function () use (&$v2) { + return $v2; + }]); + $dep3 = new CallbackDependency(['callback' => function () { + return 'fixed'; + }]); + + $chained = new ChainedDependency([ + 'dependencies' => [$dep1, $dep2, $dep3], + 'dependOnAll' => true, + ]); + + $chained->evaluateDependency($this->cache); + $v2 = 'changed'; + $this->assertTrue($chained->isChanged($this->cache)); + } + + public function testThreeDependenciesDependOnAllFalseMiddleUnchanged(): void + { + $v1 = 1; + $v3 = 3; + $dep1 = new CallbackDependency(['callback' => function () use (&$v1) { + return $v1; + }]); + $dep2 = new CallbackDependency(['callback' => function () { + return 'stable'; + }]); + $dep3 = new CallbackDependency(['callback' => function () use (&$v3) { + return $v3; + }]); + + $chained = new ChainedDependency([ + 'dependencies' => [$dep1, $dep2, $dep3], + 'dependOnAll' => false, + ]); + + $chained->evaluateDependency($this->cache); + $v1 = 10; + $v3 = 30; + $this->assertFalse($chained->isChanged($this->cache)); + } +} diff --git a/tests/framework/caching/DummyCacheTest.php b/tests/framework/caching/DummyCacheTest.php new file mode 100644 index 00000000000..f206cd68f58 --- /dev/null +++ b/tests/framework/caching/DummyCacheTest.php @@ -0,0 +1,167 @@ +cache = new DummyCache(); + } + + public function testGetAlwaysReturnsFalse(): void + { + $this->cache->set('key', 'value'); + $this->assertFalse($this->cache->get('key')); + } + + public function testSetReturnsTrue(): void + { + $this->assertTrue($this->cache->set('key', 'value')); + } + + public function testAddReturnsTrue(): void + { + $this->assertTrue($this->cache->add('key', 'value')); + } + + public function testDeleteReturnsTrue(): void + { + $this->assertTrue($this->cache->delete('key')); + } + + public function testFlushReturnsTrue(): void + { + $this->assertTrue($this->cache->flush()); + } + + public function testSetWithDurationStillReturnsFalseOnGet(): void + { + $this->cache->set('key', 'value', 3600); + $this->assertFalse($this->cache->get('key')); + } + + public function testMultipleSetsThenGet(): void + { + $this->cache->set('a', 1); + $this->cache->set('b', 2); + $this->assertFalse($this->cache->get('a')); + $this->assertFalse($this->cache->get('b')); + } + + public function testMultiGet(): void + { + $this->cache->set('k1', 'v1'); + $this->cache->set('k2', 'v2'); + + $result = $this->cache->multiGet(['k1', 'k2', 'k3']); + $this->assertFalse($result['k1']); + $this->assertFalse($result['k2']); + $this->assertFalse($result['k3']); + } + + public function testMultiSet(): void + { + $this->cache->multiSet(['k1' => 'v1', 'k2' => 'v2']); + $this->assertFalse($this->cache->get('k1')); + $this->assertFalse($this->cache->get('k2')); + } + + public function testMultiAdd(): void + { + $this->cache->multiAdd(['k1' => 'v1', 'k2' => 'v2']); + $this->assertFalse($this->cache->get('k1')); + $this->assertFalse($this->cache->get('k2')); + } + + public function testExists(): void + { + $this->cache->set('key', 'value'); + $this->assertFalse($this->cache->exists('key')); + } + + public function testArrayAccess(): void + { + $this->cache['key'] = 'value'; + $this->assertFalse(isset($this->cache['key'])); + $this->assertFalse($this->cache['key']); + } + + public function testGetOrSetAlwaysCallsCallable(): void + { + $callCount = 0; + $callable = function ($cache) use (&$callCount) { + $callCount++; + return 'generated'; + }; + + $result1 = $this->cache->getOrSet('key', $callable); + $result2 = $this->cache->getOrSet('key', $callable); + + $this->assertSame('generated', $result1); + $this->assertSame('generated', $result2); + $this->assertSame(2, $callCount); + } + + public function testSetWithDependency(): void + { + $dependency = new ExpressionDependency(['expression' => '1 + 1']); + + $this->assertTrue($this->cache->set('key', 'value', 0, $dependency)); + $this->assertFalse($this->cache->get('key')); + } + + public function testKeyPrefix(): void + { + $this->cache->keyPrefix = 'test_prefix_'; + $this->cache->set('key', 'value'); + $this->assertFalse($this->cache->get('key')); + } + + public function testCanBeUsedAsCacheComponent(): void + { + $this->mockApplication([ + 'components' => [ + 'cache' => [ + 'class' => DummyCache::class, + ], + ], + ]); + + $cache = \Yii::$app->cache; + $this->assertInstanceOf(DummyCache::class, $cache); + $this->assertTrue($cache->set('test', 'value')); + $this->assertFalse($cache->get('test')); + } + + public function testDefaultDuration(): void + { + $this->cache->defaultDuration = 3600; + $this->assertTrue($this->cache->set('key', 'value')); + $this->assertFalse($this->cache->get('key')); + } + + public function testAddAfterSet(): void + { + $this->cache->set('key', 'original'); + $this->assertTrue($this->cache->add('key', 'new')); + } +} diff --git a/tests/framework/caching/ExpressionDependencyTest.php b/tests/framework/caching/ExpressionDependencyTest.php new file mode 100644 index 00000000000..57a9a4a039f --- /dev/null +++ b/tests/framework/caching/ExpressionDependencyTest.php @@ -0,0 +1,166 @@ +cache = new ArrayCache(); + } + + public function testDefaultExpressionIsTrue(): void + { + $dependency = new ExpressionDependency(); + $this->assertSame('true', $dependency->expression); + } + + public function testDefaultParamsIsNull(): void + { + $dependency = new ExpressionDependency(); + $this->assertNull($dependency->params); + } + + public function testNotChangedWhenExpressionReturnsSameValue(): void + { + $dependency = new ExpressionDependency([ + 'expression' => '1 + 1', + ]); + + $dependency->evaluateDependency($this->cache); + $this->assertSame(2, $dependency->data); + $this->assertFalse($dependency->isChanged($this->cache)); + } + + public function testDefaultExpressionNotChanged(): void + { + $dependency = new ExpressionDependency(); + + $dependency->evaluateDependency($this->cache); + $this->assertTrue($dependency->data); + $this->assertFalse($dependency->isChanged($this->cache)); + } + + public function testStringExpression(): void + { + $dependency = new ExpressionDependency([ + 'expression' => '"hello" . " " . "world"', + ]); + + $dependency->evaluateDependency($this->cache); + $this->assertSame('hello world', $dependency->data); + $this->assertFalse($dependency->isChanged($this->cache)); + } + + public function testExpressionWithParams(): void + { + $dependency = new ExpressionDependency([ + 'expression' => '$this->params["multiplier"] * 10', + 'params' => ['multiplier' => 5], + ]); + + $dependency->evaluateDependency($this->cache); + $this->assertSame(50, $dependency->data); + $this->assertFalse($dependency->isChanged($this->cache)); + } + + public function testChangedWhenParamsChange(): void + { + $dependency = new ExpressionDependency([ + 'expression' => '$this->params["value"]', + 'params' => ['value' => 'original'], + ]); + + $dependency->evaluateDependency($this->cache); + $this->assertSame('original', $dependency->data); + + $dependency->params = ['value' => 'modified']; + $this->assertTrue($dependency->isChanged($this->cache)); + } + + public function testExpressionWithArrayResult(): void + { + $dependency = new ExpressionDependency([ + 'expression' => '[1, 2, 3]', + ]); + + $dependency->evaluateDependency($this->cache); + $this->assertSame([1, 2, 3], $dependency->data); + $this->assertFalse($dependency->isChanged($this->cache)); + } + + public function testExpressionWithNullResult(): void + { + $dependency = new ExpressionDependency([ + 'expression' => 'null', + ]); + + $dependency->evaluateDependency($this->cache); + $this->assertNull($dependency->data); + $this->assertFalse($dependency->isChanged($this->cache)); + } + + public function testExpressionWithPhpFunction(): void + { + $dependency = new ExpressionDependency([ + 'expression' => 'strlen("test")', + ]); + + $dependency->evaluateDependency($this->cache); + $this->assertSame(4, $dependency->data); + $this->assertFalse($dependency->isChanged($this->cache)); + } + + public function testExpressionWithTernary(): void + { + $dependency = new ExpressionDependency([ + 'expression' => '$this->params["flag"] ? "yes" : "no"', + 'params' => ['flag' => true], + ]); + + $dependency->evaluateDependency($this->cache); + $this->assertSame('yes', $dependency->data); + + $dependency->params = ['flag' => false]; + $this->assertTrue($dependency->isChanged($this->cache)); + } + + public function testParamsAccessibleViaThisParams(): void + { + $dependency = new ExpressionDependency([ + 'expression' => 'array_sum($this->params)', + 'params' => [10, 20, 30], + ]); + + $dependency->evaluateDependency($this->cache); + $this->assertSame(60, $dependency->data); + } + + public function testExpressionWithBooleanResult(): void + { + $dependency = new ExpressionDependency([ + 'expression' => '5 > 3', + ]); + + $dependency->evaluateDependency($this->cache); + $this->assertTrue($dependency->data); + $this->assertFalse($dependency->isChanged($this->cache)); + } +}