Skip to content

Commit

Permalink
feat(Testing): Add assert / expectation for CacheMeService
Browse files Browse the repository at this point in the history
  • Loading branch information
pionl committed Dec 13, 2022
1 parent 5ce2114 commit 5ea6f2c
Show file tree
Hide file tree
Showing 7 changed files with 374 additions and 0 deletions.
130 changes: 130 additions & 0 deletions src/Testing/Cache/Contracts/CacheMeServiceContractAssert.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,130 @@
<?php

declare(strict_types=1);

namespace LaraStrict\Testing\Cache\Contracts;

use Closure;
use Illuminate\Database\Eloquent\Model;
use LaraStrict\Cache\Constants\CacheExpirations;
use LaraStrict\Cache\Contracts\CacheMeServiceContract;
use LaraStrict\Cache\Enums\CacheMeStrategy;
use LaraStrict\Testing\AbstractExpectationCallsMap;
use PHPUnit\Framework\Assert;

class CacheMeServiceContractAssert extends AbstractExpectationCallsMap implements CacheMeServiceContract
{
/**
* @param array<CacheMeServiceContractGetExpectation> $get
* @param array<CacheMeServiceContractSetExpectation> $set
* @param array<CacheMeServiceContractFlushExpectation> $flush
* @param array<CacheMeServiceContractDeleteExpectation> $delete
* @param array<CacheMeServiceContractObserveAndFlushExpectation> $observeAndFlush
*/
public function __construct(
array $get = [],
array $set = [],
array $flush = [],
array $delete = [],
array $observeAndFlush = [],
) {
$this->setExpectations(CacheMeServiceContractGetExpectation::class, array_values(array_filter($get)));
$this->setExpectations(CacheMeServiceContractSetExpectation::class, array_values(array_filter($set)));
$this->setExpectations(CacheMeServiceContractFlushExpectation::class, array_values(array_filter($flush)));
$this->setExpectations(CacheMeServiceContractDeleteExpectation::class, array_values(array_filter($delete)));
$this->setExpectations(
CacheMeServiceContractObserveAndFlushExpectation::class,
array_values(array_filter($observeAndFlush))
);
}

/**
* Tries to get the value from the cache using given strategy (by default tries memory and then repository). If
* value does not exist, creates it via callback. If repository supports tags it will use tagged store.
*
* @param Closure $getValue method is called with dependency injection
*/
public function get(
string $key,
Closure $getValue,
array $tags = [],
int $minutes = CacheExpirations::HalfDay,
CacheMeStrategy $strategy = CacheMeStrategy::MemoryAndRepository,
): mixed {
$expectation = $this->getExpectation(CacheMeServiceContractGetExpectation::class);
$message = $this->getDebugMessage();

Assert::assertEquals($expectation->key, $key, $message);
Assert::assertEquals($expectation->tags, $tags, $message);
Assert::assertEquals($expectation->minutes, $minutes, $message);
Assert::assertEquals($expectation->strategy, $strategy, $message);

return $getValue();
}

/**
* Stores given value to cache.
*/
public function set(
string $key,
mixed $value,
array $tags = [],
int $minutes = CacheExpirations::HalfDay,
CacheMeStrategy $strategy = CacheMeStrategy::MemoryAndRepository,
): void {
$expectation = $this->getExpectation(CacheMeServiceContractSetExpectation::class);
$message = $this->getDebugMessage();

Assert::assertEquals($expectation->key, $key, $message);
Assert::assertEquals($expectation->value, $value, $message);
Assert::assertEquals($expectation->tags, $tags, $message);
Assert::assertEquals($expectation->minutes, $minutes, $message);
Assert::assertEquals($expectation->strategy, $strategy, $message);
}

/**
* Flush cache for given tags (optional).
*/
public function flush(
array $tags = [],
CacheMeStrategy $strategy = CacheMeStrategy::MemoryAndRepository,
): void {
$expectation = $this->getExpectation(CacheMeServiceContractFlushExpectation::class);
$message = $this->getDebugMessage();

Assert::assertEquals($expectation->tags, $tags, $message);
Assert::assertEquals($expectation->strategy, $strategy, $message);
}

/**
* Deletes exact key withing the tags.
*/
public function delete(
string $key,
array $tags = [],
CacheMeStrategy $strategy = CacheMeStrategy::MemoryAndRepository,
): void {
$expectation = $this->getExpectation(CacheMeServiceContractDeleteExpectation::class);
$message = $this->getDebugMessage();

Assert::assertEquals($expectation->key, $key, $message);
Assert::assertEquals($expectation->tags, $tags, $message);
Assert::assertEquals($expectation->strategy, $strategy, $message);
}

/**
* Adds a observe functions for created/deleted/updated and flushes the cache.
*
* @param array|Closure $tags If closure, model is passed to the closure. Closure should return an array
* of tags to use. If empty, no flush will be done.
* @param class-string<Model> $modelClass
*/
public function observeAndFlush(Closure|array $tags, string $modelClass): void
{
$expectation = $this->getExpectation(CacheMeServiceContractObserveAndFlushExpectation::class);
$message = $this->getDebugMessage();

Assert::assertEquals($expectation->tags, $tags, $message);
Assert::assertEquals($expectation->modelClass, $modelClass, $message);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
<?php

declare(strict_types=1);

namespace LaraStrict\Testing\Cache\Contracts;

use LaraStrict\Cache\Enums\CacheMeStrategy;

final class CacheMeServiceContractDeleteExpectation
{
public function __construct(
public readonly string $key,
public readonly array $tags = [],
public readonly CacheMeStrategy $strategy = CacheMeStrategy::MemoryAndRepository,
) {
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
<?php

declare(strict_types=1);

namespace LaraStrict\Testing\Cache\Contracts;

use LaraStrict\Cache\Enums\CacheMeStrategy;

final class CacheMeServiceContractFlushExpectation
{
public function __construct(
public readonly array $tags = [],
public readonly CacheMeStrategy $strategy = CacheMeStrategy::MemoryAndRepository,
) {
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
<?php

declare(strict_types=1);

namespace LaraStrict\Testing\Cache\Contracts;

use LaraStrict\Cache\Constants\CacheExpirations;
use LaraStrict\Cache\Enums\CacheMeStrategy;

final class CacheMeServiceContractGetExpectation
{
public function __construct(
public readonly string $key,
public readonly array $tags = [],
public readonly int $minutes = CacheExpirations::HalfDay,
public readonly CacheMeStrategy $strategy = CacheMeStrategy::MemoryAndRepository,
) {
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
<?php

declare(strict_types=1);

namespace LaraStrict\Testing\Cache\Contracts;

use Closure;

final class CacheMeServiceContractObserveAndFlushExpectation
{
public function __construct(
public readonly Closure|array $tags,
public readonly string $modelClass,
) {
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
<?php

declare(strict_types=1);

namespace LaraStrict\Testing\Cache\Contracts;

use LaraStrict\Cache\Constants\CacheExpirations;
use LaraStrict\Cache\Enums\CacheMeStrategy;

final class CacheMeServiceContractSetExpectation
{
public function __construct(
public readonly string $key,
public readonly mixed $value,
public readonly array $tags = [],
public readonly int $minutes = CacheExpirations::HalfDay,
public readonly CacheMeStrategy $strategy = CacheMeStrategy::MemoryAndRepository,
) {
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,156 @@
<?php

declare(strict_types=1);

namespace Tests\LaraStrict\Feature\Testing\Cache\Contracts;

use LaraStrict\Cache\Enums\CacheMeStrategy;
use LaraStrict\Testing\AbstractExpectationCallsMap;
use LaraStrict\Testing\Cache\Contracts\CacheMeServiceContractAssert;
use LaraStrict\Testing\Cache\Contracts\CacheMeServiceContractDeleteExpectation;
use LaraStrict\Testing\Cache\Contracts\CacheMeServiceContractFlushExpectation;
use LaraStrict\Testing\Cache\Contracts\CacheMeServiceContractGetExpectation;
use LaraStrict\Testing\Cache\Contracts\CacheMeServiceContractObserveAndFlushExpectation;
use LaraStrict\Testing\Cache\Contracts\CacheMeServiceContractSetExpectation;
use LaraStrict\Testing\Concerns\AssertExpectations;
use LaraStrict\Testing\Entities\AssertExpectationEntity;
use PHPUnit\Framework\TestCase;
use Tests\LaraStrict\Feature\Database\Models\Test;

class CacheMeServiceContractAssertTest extends TestCase
{
use AssertExpectations;

private const Return = 'test';

private const Key = 'key';

protected function generateData(): array
{
$closure = static fn () => 'test';
return [
new AssertExpectationEntity(
methodName: 'get',
createAssert: static fn () => new CacheMeServiceContractAssert(
get: [new CacheMeServiceContractGetExpectation(key: self::Key,)]
),
call: static fn (CacheMeServiceContractAssert $assert) => $assert->get(
key: self::Key,
getValue: static fn () => self::Return
),
checkResult: true,
expectedResult: 'test'
),
new AssertExpectationEntity(
methodName: 'set',
createAssert: static fn () => new CacheMeServiceContractAssert(
set: [new CacheMeServiceContractSetExpectation(
key: self::Key,
value: self::Return,
tags: [self::Return],
minutes: 230,
strategy: CacheMeStrategy::Memory
)]
),
call: static fn (CacheMeServiceContractAssert $assert) => $assert->set(
key: self::Key,
value: self::Return,
tags: [self::Return],
minutes: 230,
strategy: CacheMeStrategy::Memory
),
checkResult: false,
),
new AssertExpectationEntity(
methodName: 'set',
createAssert: static fn () => new CacheMeServiceContractAssert(
set: [new CacheMeServiceContractSetExpectation(key: self::Key, value: self::Return)]
),
call: static fn (CacheMeServiceContractAssert $assert) => $assert->set(
key: self::Key,
value: self::Return
),
checkResult: false,
),
new AssertExpectationEntity(
methodName: 'flush',
createAssert: static fn () => new CacheMeServiceContractAssert(
flush: [new CacheMeServiceContractFlushExpectation()]
),
call: static fn (CacheMeServiceContractAssert $assert) => $assert->flush(),
checkResult: false,
),
new AssertExpectationEntity(
methodName: 'flush',
createAssert: static fn () => new CacheMeServiceContractAssert(
flush: [new CacheMeServiceContractFlushExpectation(
tags: [self::Return],
strategy: CacheMeStrategy::Memory
)]
),
call: static fn (CacheMeServiceContractAssert $assert) => $assert->flush(
tags: [self::Return],
strategy: CacheMeStrategy::Memory
),
checkResult: false,
),
new AssertExpectationEntity(
methodName: 'delete',
createAssert: static fn () => new CacheMeServiceContractAssert(
delete: [new CacheMeServiceContractDeleteExpectation(key: self::Key,)]
),
call: static fn (CacheMeServiceContractAssert $assert) => $assert->delete(key: self::Key,),
checkResult: false,
),
new AssertExpectationEntity(
methodName: 'delete',
createAssert: static fn () => new CacheMeServiceContractAssert(
delete: [new CacheMeServiceContractDeleteExpectation(
key: self::Key,
tags: [self::Return],
strategy: CacheMeStrategy::Memory
)]
),
call: static fn (CacheMeServiceContractAssert $assert) => $assert->delete(
key: self::Key,
tags: [self::Return],
strategy: CacheMeStrategy::Memory
),
checkResult: false,
),
new AssertExpectationEntity(
methodName: 'observeAndFlush',
createAssert: static fn () => new CacheMeServiceContractAssert(
observeAndFlush: [new CacheMeServiceContractObserveAndFlushExpectation(
tags: [self::Key],
modelClass: Test::class,
)]
),
call: static fn (CacheMeServiceContractAssert $assert) => $assert->observeAndFlush(
tags: [self::Key],
modelClass: Test::class,
),
checkResult: false,
),
new AssertExpectationEntity(
methodName: 'observeAndFlush',
createAssert: static fn () => new CacheMeServiceContractAssert(
observeAndFlush: [new CacheMeServiceContractObserveAndFlushExpectation(
tags: static fn () => 'test',
modelClass: Test::class,
)]
),
call: static fn (CacheMeServiceContractAssert $assert) => $assert->observeAndFlush(
tags: $closure,
modelClass: Test::class,
),
checkResult: false,
),
];
}

protected function createEmptyAssert(): AbstractExpectationCallsMap
{
return new CacheMeServiceContractAssert();
}
}

0 comments on commit 5ea6f2c

Please sign in to comment.