Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Tests #14

Closed
wants to merge 16 commits into from
60 changes: 23 additions & 37 deletions src/CachesValue.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@
use Illuminate\Bus\Queueable;
use Illuminate\Console\Scheduling\CallbackEvent;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Bus\PendingDispatch;
use Illuminate\Support\Arr;
use Illuminate\Support\Facades\Blade;
use Illuminate\Support\Facades\Cache;
Expand Down Expand Up @@ -45,27 +44,18 @@ trait CachesValue
*/
protected $expression = null;

/**
* The parameters this cache should be stored with.
*
* @var array<string, mixed>
*/
/** @var array<string, mixed> */
protected $parameters = [];

/**
* Indicates whether this cache is currently updating or not.
*
* @var bool
*/
private $isUpdating = false;
private bool $isUpdating = false;

/**
* Update the cached value, this method expects an event if
* the cacher is not static.
*
* @internal You shouldn't call this yourself, use the `CachesValue::update` method instead.
* @internal You shouldn't call this yourself.
*/
final public function handle($event = null): void
final public function handle($event = null): mixed
{
$this->isUpdating = true;

Expand All @@ -78,14 +68,16 @@ final public function handle($event = null): void
: $this->run($event);

if (is_null($value)) {
return;
return null;
}

Cache::driver($driver)->forever($cacheKey, $value);

PermanentCacheUpdated::dispatch($this);

$this->isUpdating = false;

return $value;
}

public function getParameters()
Expand Down Expand Up @@ -115,23 +107,28 @@ private static function store($parameters): array

public function shouldBeUpdating(): bool
{
return app()->runningInConsole();
return
! app()->environment('testing') &&
app()->runningInConsole();
}

/**
* Manually force a static cache to update.
*/
final public static function update($parameters = []): ?PendingDispatch
final public static function update($parameters = []): mixed
{
$instance = app()->make(static::class, $parameters);

if (! is_subclass_of(static::class, ShouldQueue::class)) {
$instance->handle();
if (
app()->runningInConsole() &&
is_subclass_of(static::class, ShouldQueue::class)
) {
dispatch($instance);

return null;
}

return dispatch($instance);
return $instance->handle();
}

/**
Expand All @@ -152,27 +149,16 @@ final public static function get($default = null, bool $update = false): mixed

$cache = Cache::driver($driver);

if ($update && ! $cache->has($cacheKey)) {
static::update($parameters ?? [])->onConnection('sync');
if (
$update ||
! $cache->has($cacheKey)
) {
return static::update($parameters ?? []);
}

return $cache->get($cacheKey, $default);
}

/**
* Force an update of the cache and return the updated value.
*
* @return V|mixed
*/
final public static function updateAndGet($parameters = []): mixed
{
[$driver, $cacheKey] = self::store($parameters);

static::update($parameters)->onConnection('sync');

return Cache::driver($driver)->get($cacheKey);
}

/**
* Get the cached value this cacher provides.
*
Expand Down Expand Up @@ -253,7 +239,7 @@ private static function parseCacheString($class, ?string $store, ?array $paramet
}

$cacheDriver ??= config('cache.default');
$cacheKey ??= preg_replace('/[^A-Za-z0-9]+/', '_', strtolower(\Str::snake($class)));
$cacheKey ??= preg_replace('/[^A-Za-z0-9]+/', '_', strtolower(snake_case($class)));

if ($parameters) {
$cacheKey .= ':'.http_build_query($parameters);
Expand Down
10 changes: 10 additions & 0 deletions src/PermanentCache.php
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,16 @@ public function caches($registeredCaches): self
return $this;
}

/**
* Update all registered permanent caches
*/
public function update()
{
foreach ($this->cachers as $cacher) {
$cacher->update();
}
}

public function configuredCaches(): SplObjectStorage
{
return $this->cachers;
Expand Down
5 changes: 0 additions & 5 deletions tests/ExampleTest.php

This file was deleted.

19 changes: 19 additions & 0 deletions tests/Unit/CachedComponent/CachedComponent.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
<?php

class CachedComponent extends \Vormkracht10\PermanentCache\CachedComponent
{
protected $store = 'file:unique-cache-key';

public function __construct(public string $value = '')
{
}

public function render(): string
{
$value = $this->value ?? str_random();

return <<<'HTML'
<div>This is a {{ $value ?? 'cached' }} component!</div>
HTML;
}
}
29 changes: 29 additions & 0 deletions tests/Unit/CachedComponent/CachedComponentTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
<?php

use Illuminate\Support\Facades\Blade;

require_once 'tests/Unit/CachedComponent/CachedComponent.php';

beforeEach(function () {
Cache::driver('file')->clear();
(fn () => $this->cachers = new \SplObjectStorage)->call(app(\Vormkracht10\PermanentCache\PermanentCache::class));
});

test('test cached component is cached second time', function () {
$firstRunOutput = Blade::renderComponent(new CachedComponent);
$secondRunOutput = Blade::renderComponent(new CachedComponent);

$this->assertEquals($firstRunOutput, $secondRunOutput);
});

test('test cached component with parameters is cached correctly', function () {
$randomString = str_random();

$cachedComponentWithParameters = new CachedComponent(value: $randomString);

$firstRunOutput = Blade::renderComponent($cachedComponentWithParameters);
$secondRunOutput = Blade::renderComponent($cachedComponentWithParameters);

$this->assertEquals($firstRunOutput, '<div>This is a '.$randomString.' component!</div>');
$this->assertEquals($secondRunOutput, '<div>This is a '.$randomString.' component!</div>');
});
28 changes: 28 additions & 0 deletions tests/Unit/CachedComponent/ScheduledAndQueuedCachedComponent.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
<?php

use Illuminate\Contracts\Queue\ShouldQueue;
use Vormkracht10\PermanentCache\CachedComponent;
use Vormkracht10\PermanentCache\Scheduled;

class ScheduledAndQueuedCachedComponent extends CachedComponent implements Scheduled, ShouldQueue
{
protected $store = 'file:unique-cache-key';

public function __construct(public string $value = '')
{
}

public function render(): string
{
$value = $this->value ?? str_random();

return <<<'HTML'
<div>This is a {{ $value ?? 'cached' }} component!</div>
HTML;
}

public static function schedule($callback)
{
return $callback->everyMinute();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
<?php

use Illuminate\Console\Scheduling\Schedule;
use Illuminate\Support\Facades\Queue;
use Vormkracht10\PermanentCache\Facades\PermanentCache;

require_once 'tests/Unit/CachedComponent/ScheduledAndQueuedCachedComponent.php';

beforeEach(function () {
Cache::driver('file')->clear();
Queue::fake();

(fn () => $this->cachers = new \SplObjectStorage)->call(app(\Vormkracht10\PermanentCache\PermanentCache::class));
});

test('test scheduled queued cached component gets scheduled', function () {
PermanentCache::caches([
ScheduledAndQueuedCachedComponent::class,
]);

$events = collect(app(Schedule::class)->events())
->filter(fn ($schedule) => $schedule->description === 'ScheduledAndQueuedCachedComponent');

expect($events)->toHaveCount(1);
expect($events->first()->expression)->toBe('* * * * *');
});

test('test scheduled queued cached component with parameters gets scheduled', function () {
PermanentCache::caches([
ScheduledAndQueuedCachedComponent::class => ['parameter' => 'test cached'],
]);

$events = collect(app(Schedule::class)->events())
->filter(fn ($schedule) => $schedule->description === 'ScheduledAndQueuedCachedComponent');

expect($events)->toHaveCount(1);
expect($events->first()->expression)->toBe('* * * * *');
});

test('test scheduled queued cached component gets executed', function () {
PermanentCache::caches([
ScheduledAndQueuedCachedComponent::class => ['parameter' => 'test cached'],
]);

$events = collect(app(Schedule::class)->events())
->filter(fn ($schedule) => $schedule->description === 'ScheduledAndQueuedCachedComponent');

expect($events)->toHaveCount(1);
expect($events->first()->expression)->toBe('* * * * *');

PermanentCache::update();

Queue::assertPushed(ScheduledAndQueuedCachedComponent::class);
});
26 changes: 26 additions & 0 deletions tests/Unit/CachedComponent/ScheduledCachedComponent.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
<?php

use Vormkracht10\PermanentCache\Scheduled;

class ScheduledCachedComponent extends \Vormkracht10\PermanentCache\CachedComponent implements Scheduled
{
protected $store = 'file:unique-cache-key';

public function __construct(public string $value = '')
{
}

public function render(): string
{
$value = $this->value;

return <<<'HTML'
<div>This is a {{ $value ?? 'cached' }} component!</div>
HTML;
}

public static function schedule($callback)
{
return $callback->everyMinute();
}
}
45 changes: 45 additions & 0 deletions tests/Unit/CachedComponent/ScheduledCachedComponentTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
<?php

use Illuminate\Support\Facades\Event;
use Vormkracht10\PermanentCache\Events\PermanentCacheUpdated;
use Vormkracht10\PermanentCache\Events\PermanentCacheUpdating;
use Vormkracht10\PermanentCache\Facades\PermanentCache;

require_once 'tests/Unit/CachedComponent/ScheduledCachedComponent.php';

beforeEach(function () {
Cache::driver('file')->clear();

(fn () => $this->cachers = new \SplObjectStorage)->call(app(\Vormkracht10\PermanentCache\PermanentCache::class));
});

test('test scheduled cached component gets scheduled', function () {
PermanentCache::caches([
ScheduledCachedComponent::class,
]);

$events = collect(app(\Illuminate\Console\Scheduling\Schedule::class)->events())
->filter(fn ($schedule) => $schedule->description === 'ScheduledCachedComponent');

expect($events)->toHaveCount(1);
expect($events->first()->expression)->toBe('* * * * *');
});

test('test scheduled cached component with parameters gets scheduled', function () {
Event::fake();

PermanentCache::caches([
ScheduledCachedComponent::class => ['parameter' => 'test cached'],
]);

$events = collect(app(\Illuminate\Console\Scheduling\Schedule::class)->events())
->filter(fn ($schedule) => $schedule->description === 'ScheduledCachedComponent');

expect($events)->toHaveCount(1);
expect($events->first()->expression)->toBe('* * * * *');

PermanentCache::update();

Event::assertDispatchedTimes(PermanentCacheUpdating::class, times: 1);
Event::assertDispatchedTimes(PermanentCacheUpdated::class, times : 1);
});
Loading
Loading