diff --git a/app/Liquid/Filters/Data.php b/app/Liquid/Filters/Data.php index 4437032..bbf613b 100644 --- a/app/Liquid/Filters/Data.php +++ b/app/Liquid/Filters/Data.php @@ -63,4 +63,19 @@ class Data extends FiltersProvider return $grouped; } + + /** + * Return a random element from an array + * + * @param array $array The array to sample from + * @return mixed A random element from the array + */ + public function sample(array $array): mixed + { + if (empty($array)) { + return null; + } + + return $array[array_rand($array)]; + } } diff --git a/app/Liquid/Filters/Date.php b/app/Liquid/Filters/Date.php new file mode 100644 index 0000000..d8cc309 --- /dev/null +++ b/app/Liquid/Filters/Date.php @@ -0,0 +1,25 @@ +subDays($days)->toDateString(); + } +} diff --git a/app/Models/Plugin.php b/app/Models/Plugin.php index 72da730..0dceddf 100644 --- a/app/Models/Plugin.php +++ b/app/Models/Plugin.php @@ -4,6 +4,7 @@ namespace App\Models; use App\Liquid\FileSystems\InlineTemplatesFileSystem; use App\Liquid\Filters\Data; +use App\Liquid\Filters\Date; use App\Liquid\Filters\Localization; use App\Liquid\Filters\Numbers; use App\Liquid\Filters\StringMarkup; @@ -215,6 +216,7 @@ class Plugin extends Model { $replacements = [ 'date: "%N"' => 'date: "u"', + 'date: "%u"' => 'date: "u"', '%-m/%-d/%Y' => 'm/d/Y', ]; @@ -271,11 +273,12 @@ class Plugin extends Model ); // Register all custom filters - $environment->filterRegistry->register(Numbers::class); $environment->filterRegistry->register(Data::class); + $environment->filterRegistry->register(Date::class); + $environment->filterRegistry->register(Localization::class); + $environment->filterRegistry->register(Numbers::class); $environment->filterRegistry->register(StringMarkup::class); $environment->filterRegistry->register(Uniqueness::class); - $environment->filterRegistry->register(Localization::class); // Register the template tag for inline templates $environment->tagRegistry->register(TemplateTag::class); diff --git a/tests/Unit/Liquid/Filters/DataTest.php b/tests/Unit/Liquid/Filters/DataTest.php index 8145088..5937670 100644 --- a/tests/Unit/Liquid/Filters/DataTest.php +++ b/tests/Unit/Liquid/Filters/DataTest.php @@ -237,3 +237,43 @@ test('group_by filter handles mixed data types as keys', function () { '' => [['name' => 'Alice', 'active' => null]], // PHP converts null keys to empty string ]); }); + +test('sample filter returns a random element from array', function () { + $filter = new Data(); + $array = ['1', '2', '3', '4', '5']; + + $result = $filter->sample($array); + expect($result)->toBeIn($array); +}); + +test('sample filter returns a random element from string array', function () { + $filter = new Data(); + $array = ['cat', 'dog']; + + $result = $filter->sample($array); + expect($result)->toBeIn($array); +}); + +test('sample filter returns null for empty array', function () { + $filter = new Data(); + $array = []; + + $result = $filter->sample($array); + expect($result)->toBeNull(); +}); + +test('sample filter returns the only element from single element array', function () { + $filter = new Data(); + $array = ['single']; + + $result = $filter->sample($array); + expect($result)->toBe('single'); +}); + +test('sample filter works with mixed data types', function () { + $filter = new Data(); + $array = [1, 'string', true, null, ['nested']]; + + $result = $filter->sample($array); + expect($result)->toBeIn($array); +}); diff --git a/tests/Unit/Liquid/Filters/DateTest.php b/tests/Unit/Liquid/Filters/DateTest.php new file mode 100644 index 0000000..5813e10 --- /dev/null +++ b/tests/Unit/Liquid/Filters/DateTest.php @@ -0,0 +1,32 @@ +subDays(3)->toDateString(); + + expect($filter->days_ago(3))->toBe($threeDaysAgo); +}); + +test('days_ago filter handles string input', function () { + $filter = new Date(); + $fiveDaysAgo = Carbon::now()->subDays(5)->toDateString(); + + expect($filter->days_ago('5'))->toBe($fiveDaysAgo); +}); + +test('days_ago filter with zero days returns today', function () { + $filter = new Date(); + $today = Carbon::now()->toDateString(); + + expect($filter->days_ago(0))->toBe($today); +}); + +test('days_ago filter with large number works correctly', function () { + $filter = new Date(); + $hundredDaysAgo = Carbon::now()->subDays(100)->toDateString(); + + expect($filter->days_ago(100))->toBe($hundredDaysAgo); +});