bucketableRange(); $expected = new SeriesResult($range->days(), [new Series('Approved', [1, 2, 3, 4, 5, 6, 7])]); $stat = new class($expected) extends DailySeriesStat { public bool $seriesWasCalled = false; public function __construct(private readonly SeriesResult $result) {} public function key(): string { return 'fake'; } public function label(): string { return 'Fake'; } protected function series(DateRange $range, array $days): SeriesResult { $this->seriesWasCalled = true; return $this->result; } }; $result = $stat->for($range); $this->assertTrue($stat->seriesWasCalled); $this->assertSame($expected, $result); } public function test_for_returns_a_too_wide_result_without_calling_series_on_a_non_bucketable_range(): void { Carbon::setTestNow('2026-07-15 13:45:00'); $range = DateRange::preset('all'); $stat = new class extends DailySeriesStat { public bool $seriesWasCalled = false; public function key(): string { return 'fake'; } public function label(): string { return 'Fake'; } protected function series(DateRange $range, array $days): SeriesResult { $this->seriesWasCalled = true; return new SeriesResult([], []); } }; $result = $stat->for($range); $this->assertFalse($stat->seriesWasCalled); $this->assertTrue($result->isTooWide()); } public function test_for_passes_the_ranges_days_through_to_series(): void { $range = $this->bucketableRange(); $stat = new class extends DailySeriesStat { /** @var array|null */ public ?array $receivedDays = null; public function key(): string { return 'fake'; } public function label(): string { return 'Fake'; } protected function series(DateRange $range, array $days): SeriesResult { $this->receivedDays = $days; return new SeriesResult($days, []); } }; $stat->for($range); $this->assertSame($range->days(), $stat->receivedDays); } }