diff --git a/.ci/rector.php b/.ci/rector.php index 8f33d1615d..6e98485438 100644 --- a/.ci/rector.php +++ b/.ci/rector.php @@ -35,7 +35,7 @@ return RectorConfig::configure() __DIR__ . '/../bootstrap', __DIR__ . '/../config', __DIR__ . '/../public', - __DIR__ . '/../resources', + __DIR__ . '/../resources/lang/en_US', __DIR__ . '/../routes', __DIR__ . '/../tests', ]) diff --git a/bootstrap/app.php b/bootstrap/app.php index e5fc51d13d..9c9c5c85b1 100644 --- a/bootstrap/app.php +++ b/bootstrap/app.php @@ -21,6 +21,11 @@ declare(strict_types=1); +use Illuminate\Foundation\Application; +use Illuminate\Contracts\Http\Kernel; +use Illuminate\Contracts\Debug\ExceptionHandler; +use FireflyIII\Exceptions\Handler; + /* |-------------------------------------------------------------------------- | Create The Application @@ -45,7 +50,7 @@ if (!function_exists('envNonEmpty')) { { $result = env($key, $default); // @phpstan-ignore-line if ('' === $result) { - $result = $default; + return $default; } return $result; @@ -65,7 +70,7 @@ if (!function_exists('stringIsEqual')) { } } -$app = new Illuminate\Foundation\Application( +$app = new Application( (string)realpath(__DIR__ . '/../') ); @@ -81,7 +86,7 @@ $app = new Illuminate\Foundation\Application( */ $app->singleton( - Illuminate\Contracts\Http\Kernel::class, + Kernel::class, FireflyIII\Http\Kernel::class ); @@ -91,8 +96,8 @@ $app->singleton( ); $app->singleton( - Illuminate\Contracts\Debug\ExceptionHandler::class, - FireflyIII\Exceptions\Handler::class + ExceptionHandler::class, + Handler::class ); /* diff --git a/public/index.php b/public/index.php index 22c05fd592..e1efbd4614 100644 --- a/public/index.php +++ b/public/index.php @@ -1,4 +1,9 @@ make(Illuminate\Contracts\Http\Kernel::class); +$kernel = $app->make(Kernel::class); $response = $kernel->handle( - $request = Illuminate\Http\Request::capture() + $request = Request::capture() ); $response->send(); diff --git a/routes/breadcrumbs.php b/routes/breadcrumbs.php index 2ea63de4d2..0519d8eacd 100644 --- a/routes/breadcrumbs.php +++ b/routes/breadcrumbs.php @@ -54,12 +54,11 @@ if (!function_exists('limitStringLength')) { { $maxChars = 75; $length = strlen($string); - $result = $string; if ($length > $maxChars) { - $result = substr_replace($string, ' ... ', (int)($maxChars / 2), $length - $maxChars); + return substr_replace($string, ' ... ', (int)($maxChars / 2), $length - $maxChars); } - return $result; + return $string; } } @@ -109,7 +108,7 @@ Breadcrumbs::for( $breadcrumbs->parent('accounts.index', $what); $breadcrumbs->push(limitStringLength($account->name), route('accounts.show.all', [$account->id])); - if (null !== $start && null !== $end) { + if ($start instanceof Carbon && $end instanceof Carbon) { $title = trans( 'firefly.between_dates_breadcrumb', [ @@ -451,7 +450,7 @@ Breadcrumbs::for( static function (Generator $breadcrumbs, ?Carbon $start = null, ?Carbon $end = null): void { $breadcrumbs->parent('budgets.index'); $breadcrumbs->push(trans('firefly.journals_without_budget'), route('budgets.no-budget')); - if (null !== $start && null !== $end) { + if ($start instanceof Carbon && $end instanceof Carbon) { $title = trans( 'firefly.between_dates_breadcrumb', [ @@ -539,7 +538,7 @@ Breadcrumbs::for( static function (Generator $breadcrumbs, Category $category, ?Carbon $start = null, ?Carbon $end = null): void { $breadcrumbs->parent('categories.index'); $breadcrumbs->push(limitStringLength($category->name), route('categories.show', [$category->id])); - if (null !== $start && null !== $end) { + if ($start instanceof Carbon && $end instanceof Carbon) { $title = trans( 'firefly.between_dates_breadcrumb', [ @@ -566,7 +565,7 @@ Breadcrumbs::for( static function (Generator $breadcrumbs, ?Carbon $start = null, ?Carbon $end = null): void { $breadcrumbs->parent('categories.index'); $breadcrumbs->push(trans('firefly.journals_without_category'), route('categories.no-category')); - if (null !== $start && null !== $end) { + if ($start instanceof Carbon && $end instanceof Carbon) { $title = trans( 'firefly.between_dates_breadcrumb', [ @@ -965,10 +964,10 @@ Breadcrumbs::for( 'rules.create', static function (Generator $breadcrumbs, ?RuleGroup $ruleGroup = null): void { $breadcrumbs->parent('rules.index'); - if (null === $ruleGroup) { + if (!$ruleGroup instanceof RuleGroup) { $breadcrumbs->push(trans('firefly.make_new_rule_no_group'), route('rules.create')); } - if (null !== $ruleGroup) { + if ($ruleGroup instanceof RuleGroup) { $breadcrumbs->push(trans('firefly.make_new_rule', ['title' => $ruleGroup->title]), route('rules.create', [$ruleGroup])); } } @@ -1096,7 +1095,7 @@ Breadcrumbs::for( $breadcrumbs->parent('tags.index'); $breadcrumbs->push($tag->tag, route('tags.show', [$tag->id, $start, $end])); - if (null !== $start && null !== $end) { + if ($start instanceof Carbon && $end instanceof Carbon) { $title = trans( 'firefly.between_dates_breadcrumb', [ @@ -1127,7 +1126,7 @@ Breadcrumbs::for( $breadcrumbs->parent('home'); $breadcrumbs->push(trans('breadcrumbs.'.$what.'_list'), route('transactions.index', [$what])); - if (null !== $start && null !== $end) { + if ($start instanceof Carbon && $end instanceof Carbon) { // add date range: $title = trans( 'firefly.between_dates_breadcrumb', diff --git a/tests/integration/Support/Models/BillDateCalculatorTest.php b/tests/integration/Support/Models/BillDateCalculatorTest.php index c5dba4eed9..1164fce606 100644 --- a/tests/integration/Support/Models/BillDateCalculatorTest.php +++ b/tests/integration/Support/Models/BillDateCalculatorTest.php @@ -24,6 +24,8 @@ declare(strict_types=1); namespace Tests\integration\Support\Models; +use Override; +use Iterator; use Carbon\Carbon; use FireflyIII\Support\Models\BillDateCalculator; use PHPUnit\Framework\Attributes\DataProvider; @@ -40,6 +42,7 @@ final class BillDateCalculatorTest extends TestCase { private BillDateCalculator $calculator; + #[Override] protected function setUp(): void { parent::setUp(); @@ -56,25 +59,25 @@ final class BillDateCalculatorTest extends TestCase self::assertSame($expected, $result); } - public static function provideDates(): iterable + public static function provideDates(): Iterator { // Carbon $earliest, Carbon $latest, Carbon $billStart, string $period, int $skip, ?Carbon $lastPaid - return [ - // basic monthly bill.x - '1Ma' => ['earliest' => Carbon::parse('2023-11-01'), 'latest' => Carbon::parse('2023-11-30'), 'billStart' => Carbon::parse('2023-01-01'), 'period' => 'monthly', 'skip' => 0, 'lastPaid' => null, 'expected' => ['2023-11-01']], - // already paid on the first, expect it next month. - '1Mb' => ['earliest' => Carbon::parse('2023-11-01'), 'latest' => Carbon::parse('2023-11-30'), 'billStart' => Carbon::parse('2023-01-01'), 'period' => 'monthly', 'skip' => 0, 'lastPaid' => Carbon::parse('2023-11-01'), 'expected' => ['2023-12-01']], - // already paid on the 12th, expect it next month. - '1Mc' => ['earliest' => Carbon::parse('2023-11-01'), 'latest' => Carbon::parse('2023-11-30'), 'billStart' => Carbon::parse('2023-01-01'), 'period' => 'monthly', 'skip' => 0, 'lastPaid' => Carbon::parse('2023-11-12'), 'expected' => ['2023-12-01']], + // basic monthly bill.x + yield '1Ma' => [Carbon::parse('2023-11-01'), Carbon::parse('2023-11-30'), Carbon::parse('2023-01-01'), 'monthly', 0, null, ['2023-11-01']]; - // every month, start on 2024-01-30, view is quarterly - '1Md' => ['earliest' => Carbon::parse('2023-01-01'), 'latest' => Carbon::parse('2023-03-31'), 'billStart' => Carbon::parse('2023-01-29'), 'period' => 'monthly', 'skip' => 0, 'lastPaid' => null, 'expected' => ['2023-01-29', '2023-02-28', '2023-03-29']], + // already paid on the first, expect it next month. + yield '1Mb' => [Carbon::parse('2023-11-01'), Carbon::parse('2023-11-30'), Carbon::parse('2023-01-01'), 'monthly', 0, Carbon::parse('2023-11-01'), ['2023-12-01']]; - // every month, start on 2024-01-30, view is quarterly - '1Me' => ['earliest' => Carbon::parse('2024-01-01'), 'latest' => Carbon::parse('2024-03-31'), 'billStart' => Carbon::parse('2023-01-30'), 'period' => 'monthly', 'skip' => 0, 'lastPaid' => null, 'expected' => ['2024-01-30', '2024-02-29', '2024-03-30']], + // already paid on the 12th, expect it next month. + yield '1Mc' => [Carbon::parse('2023-11-01'), Carbon::parse('2023-11-30'), Carbon::parse('2023-01-01'), 'monthly', 0, Carbon::parse('2023-11-12'), ['2023-12-01']]; - // yearly not due this month. Should jump to next year. - '1Ya' => ['earliest' => Carbon::parse('2023-11-01'), 'latest' => Carbon::parse('2023-11-30'), 'billStart' => Carbon::parse('2021-05-01'), 'period' => 'yearly', 'skip' => 0, 'lastPaid' => Carbon::parse('2023-05-02'), 'expected' => ['2024-05-01']], - ]; + // every month, start on 2024-01-30, view is quarterly + yield '1Md' => [Carbon::parse('2023-01-01'), Carbon::parse('2023-03-31'), Carbon::parse('2023-01-29'), 'monthly', 0, null, ['2023-01-29', '2023-02-28', '2023-03-29']]; + + // every month, start on 2024-01-30, view is quarterly + yield '1Me' => [Carbon::parse('2024-01-01'), Carbon::parse('2024-03-31'), Carbon::parse('2023-01-30'), 'monthly', 0, null, ['2024-01-30', '2024-02-29', '2024-03-30']]; + + // yearly not due this month. Should jump to next year. + yield '1Ya' => [Carbon::parse('2023-11-01'), Carbon::parse('2023-11-30'), Carbon::parse('2021-05-01'), 'yearly', 0, Carbon::parse('2023-05-02'), ['2024-05-01']]; } } diff --git a/tests/unit/Support/Calendar/Periodicity/BimonthlyTest.php b/tests/unit/Support/Calendar/Periodicity/BimonthlyTest.php index 0c17381cad..b667107a3c 100644 --- a/tests/unit/Support/Calendar/Periodicity/BimonthlyTest.php +++ b/tests/unit/Support/Calendar/Periodicity/BimonthlyTest.php @@ -24,6 +24,7 @@ declare(strict_types=1); namespace Tests\unit\Support\Calendar\Periodicity; +use FireflyIII\Support\Calendar\Periodicity\Bimonthly; use Carbon\Carbon; use FireflyIII\Support\Calendar\Periodicity; use FireflyIII\Support\Calendar\Periodicity\Interval; @@ -42,7 +43,7 @@ final class BimonthlyTest extends IntervalTestCase { public static function factory(): Interval { - return new Periodicity\Bimonthly(); + return new Bimonthly(); } public static function provideIntervals(): array diff --git a/tests/unit/Support/Calendar/Periodicity/DailyTest.php b/tests/unit/Support/Calendar/Periodicity/DailyTest.php index 697b16d736..1c5dd1560c 100644 --- a/tests/unit/Support/Calendar/Periodicity/DailyTest.php +++ b/tests/unit/Support/Calendar/Periodicity/DailyTest.php @@ -24,6 +24,7 @@ declare(strict_types=1); namespace Tests\unit\Support\Calendar\Periodicity; +use FireflyIII\Support\Calendar\Periodicity\Daily; use Carbon\Carbon; use FireflyIII\Support\Calendar\Periodicity; use FireflyIII\Support\Calendar\Periodicity\Interval; @@ -42,7 +43,7 @@ final class DailyTest extends IntervalTestCase { public static function factory(): Interval { - return new Periodicity\Daily(); + return new Daily(); } public static function provideIntervals(): array diff --git a/tests/unit/Support/Calendar/Periodicity/FortnightlyTest.php b/tests/unit/Support/Calendar/Periodicity/FortnightlyTest.php index 8f0e2824ce..fdb8eac236 100644 --- a/tests/unit/Support/Calendar/Periodicity/FortnightlyTest.php +++ b/tests/unit/Support/Calendar/Periodicity/FortnightlyTest.php @@ -24,6 +24,7 @@ declare(strict_types=1); namespace Tests\unit\Support\Calendar\Periodicity; +use FireflyIII\Support\Calendar\Periodicity\Fortnightly; use Carbon\Carbon; use FireflyIII\Support\Calendar\Periodicity; use FireflyIII\Support\Calendar\Periodicity\Interval; @@ -42,7 +43,7 @@ final class FortnightlyTest extends IntervalTestCase { public static function factory(): Interval { - return new Periodicity\Fortnightly(); + return new Fortnightly(); } public static function provideIntervals(): array diff --git a/tests/unit/Support/Calendar/Periodicity/HalfYearlyTest.php b/tests/unit/Support/Calendar/Periodicity/HalfYearlyTest.php index acb1facfc0..f71779ce59 100644 --- a/tests/unit/Support/Calendar/Periodicity/HalfYearlyTest.php +++ b/tests/unit/Support/Calendar/Periodicity/HalfYearlyTest.php @@ -24,6 +24,7 @@ declare(strict_types=1); namespace Tests\unit\Support\Calendar\Periodicity; +use FireflyIII\Support\Calendar\Periodicity\HalfYearly; use Carbon\Carbon; use FireflyIII\Support\Calendar\Periodicity; use FireflyIII\Support\Calendar\Periodicity\Interval; @@ -42,7 +43,7 @@ final class HalfYearlyTest extends IntervalTestCase { public static function factory(): Interval { - return new Periodicity\HalfYearly(); + return new HalfYearly(); } public static function provideIntervals(): array diff --git a/tests/unit/Support/Calendar/Periodicity/MonthlyTest.php b/tests/unit/Support/Calendar/Periodicity/MonthlyTest.php index 56ce40f45e..afe440e976 100644 --- a/tests/unit/Support/Calendar/Periodicity/MonthlyTest.php +++ b/tests/unit/Support/Calendar/Periodicity/MonthlyTest.php @@ -24,6 +24,7 @@ declare(strict_types=1); namespace Tests\unit\Support\Calendar\Periodicity; +use FireflyIII\Support\Calendar\Periodicity\Monthly; use Carbon\Carbon; use FireflyIII\Support\Calendar\Periodicity; use FireflyIII\Support\Calendar\Periodicity\Interval; @@ -42,7 +43,7 @@ final class MonthlyTest extends IntervalTestCase { public static function factory(): Interval { - return new Periodicity\Monthly(); + return new Monthly(); } public static function provideIntervals(): array diff --git a/tests/unit/Support/Calendar/Periodicity/QuarterlyTest.php b/tests/unit/Support/Calendar/Periodicity/QuarterlyTest.php index defe22c283..3e73794f24 100644 --- a/tests/unit/Support/Calendar/Periodicity/QuarterlyTest.php +++ b/tests/unit/Support/Calendar/Periodicity/QuarterlyTest.php @@ -24,6 +24,7 @@ declare(strict_types=1); namespace Tests\unit\Support\Calendar\Periodicity; +use FireflyIII\Support\Calendar\Periodicity\Quarterly; use Carbon\Carbon; use FireflyIII\Support\Calendar\Periodicity; use FireflyIII\Support\Calendar\Periodicity\Interval; @@ -42,7 +43,7 @@ final class QuarterlyTest extends IntervalTestCase { public static function factory(): Interval { - return new Periodicity\Quarterly(); + return new Quarterly(); } public static function provideIntervals(): array diff --git a/tests/unit/Support/Calendar/Periodicity/WeeklyTest.php b/tests/unit/Support/Calendar/Periodicity/WeeklyTest.php index 093abce06a..f347d11222 100644 --- a/tests/unit/Support/Calendar/Periodicity/WeeklyTest.php +++ b/tests/unit/Support/Calendar/Periodicity/WeeklyTest.php @@ -24,6 +24,7 @@ declare(strict_types=1); namespace Tests\unit\Support\Calendar\Periodicity; +use FireflyIII\Support\Calendar\Periodicity\Weekly; use Carbon\Carbon; use FireflyIII\Support\Calendar\Periodicity; use FireflyIII\Support\Calendar\Periodicity\Interval; @@ -42,7 +43,7 @@ final class WeeklyTest extends IntervalTestCase { public static function factory(): Interval { - return new Periodicity\Weekly(); + return new Weekly(); } public static function provideIntervals(): array diff --git a/tests/unit/Support/Calendar/Periodicity/YearlyTest.php b/tests/unit/Support/Calendar/Periodicity/YearlyTest.php index 4b255d4d7c..27fbc1c56e 100644 --- a/tests/unit/Support/Calendar/Periodicity/YearlyTest.php +++ b/tests/unit/Support/Calendar/Periodicity/YearlyTest.php @@ -24,6 +24,7 @@ declare(strict_types=1); namespace Tests\unit\Support\Calendar\Periodicity; +use FireflyIII\Support\Calendar\Periodicity\Yearly; use Carbon\Carbon; use FireflyIII\Support\Calendar\Periodicity; use FireflyIII\Support\Calendar\Periodicity\Interval; @@ -42,7 +43,7 @@ final class YearlyTest extends IntervalTestCase { public static function factory(): Interval { - return new Periodicity\Yearly(); + return new Yearly(); } public static function provideIntervals(): array diff --git a/tests/unit/Support/NavigationAddPeriodTest.php b/tests/unit/Support/NavigationAddPeriodTest.php index 1920c16a6a..e492584c50 100644 --- a/tests/unit/Support/NavigationAddPeriodTest.php +++ b/tests/unit/Support/NavigationAddPeriodTest.php @@ -24,6 +24,8 @@ declare(strict_types=1); namespace Tests\unit\Support; +use Override; +use Iterator; use Carbon\Carbon; use FireflyIII\Support\Calendar\Periodicity; use FireflyIII\Support\Navigation; @@ -43,6 +45,7 @@ final class NavigationAddPeriodTest extends TestCase { private Navigation $navigation; + #[Override] protected function setUp(): void { parent::setUp(); @@ -108,30 +111,47 @@ final class NavigationAddPeriodTest extends TestCase self::assertSame($expected->toDateString(), $period->toDateString()); } - public static function providePeriods(): iterable + public static function providePeriods(): Iterator { - return [ - '1D' => ['frequency' => '1D', 'from' => Carbon::now(), 'expected' => Carbon::tomorrow()], - 'daily' => ['frequency' => 'daily', 'from' => Carbon::now(), 'expected' => Carbon::tomorrow()], - '1W' => ['frequency' => '1W', 'from' => Carbon::now(), 'expected' => Carbon::now()->addWeeks(1)], - 'weekly' => ['frequency' => 'weekly', 'from' => Carbon::now(), 'expected' => Carbon::now()->addWeeks(1)], - 'week' => ['frequency' => 'week', 'from' => Carbon::now(), 'expected' => Carbon::now()->addWeeks(1)], - '3M' => ['frequency' => '3M', 'from' => Carbon::now(), 'expected' => Carbon::now()->addMonthsNoOverflow(3)], - 'quarter' => ['frequency' => 'quarter', 'from' => Carbon::now(), 'expected' => Carbon::now()->addMonthsNoOverflow(3)], - 'quarterly' => ['frequency' => 'quarterly', 'from' => Carbon::now(), 'expected' => Carbon::now()->addMonthsNoOverflow(3)], - '6M' => ['frequency' => '6M', 'from' => Carbon::now(), 'expected' => Carbon::now()->addMonthsNoOverflow(6)], - 'half-year' => ['frequency' => 'half-year', 'from' => Carbon::now(), 'expected' => Carbon::now()->addMonthsNoOverflow(6)], - 'year' => ['frequency' => 'year', 'from' => Carbon::now(), 'expected' => Carbon::now()->addYears(1)], - 'yearly' => ['frequency' => 'yearly', 'from' => Carbon::now(), 'expected' => Carbon::now()->addYears(1)], - '1Y' => ['frequency' => '1Y', 'from' => Carbon::now(), 'expected' => Carbon::now()->addYears(1)], - 'last7' => ['frequency' => 'last7', 'from' => Carbon::now(), 'expected' => Carbon::now()->addDays(7)], - 'last30' => ['frequency' => 'last30', 'from' => Carbon::now(), 'expected' => Carbon::now()->addMonthsNoOverflow(1)], - 'last90' => ['frequency' => 'last90', 'from' => Carbon::now(), 'expected' => Carbon::now()->addMonthsNoOverflow(3)], - 'last365' => ['frequency' => 'last365', 'from' => Carbon::now(), 'expected' => Carbon::now()->addYears(1)], - 'MTD' => ['frequency' => 'MTD', 'from' => Carbon::now(), 'expected' => Carbon::now()->addMonthsNoOverflow(1)], - 'QTD' => ['frequency' => 'QTD', 'from' => Carbon::now(), 'expected' => Carbon::now()->addMonthsNoOverflow(3)], - 'YTD' => ['frequency' => 'YTD', 'from' => Carbon::now(), 'expected' => Carbon::now()->addYears(1)], - ]; + yield '1D' => ['1D', Carbon::now(), Carbon::tomorrow()]; + + yield 'daily' => ['daily', Carbon::now(), Carbon::tomorrow()]; + + yield '1W' => ['1W', Carbon::now(), Carbon::now()->addWeeks(1)]; + + yield 'weekly' => ['weekly', Carbon::now(), Carbon::now()->addWeeks(1)]; + + yield 'week' => ['week', Carbon::now(), Carbon::now()->addWeeks(1)]; + + yield '3M' => ['3M', Carbon::now(), Carbon::now()->addMonthsNoOverflow(3)]; + + yield 'quarter' => ['quarter', Carbon::now(), Carbon::now()->addMonthsNoOverflow(3)]; + + yield 'quarterly' => ['quarterly', Carbon::now(), Carbon::now()->addMonthsNoOverflow(3)]; + + yield '6M' => ['6M', Carbon::now(), Carbon::now()->addMonthsNoOverflow(6)]; + + yield 'half-year' => ['half-year', Carbon::now(), Carbon::now()->addMonthsNoOverflow(6)]; + + yield 'year' => ['year', Carbon::now(), Carbon::now()->addYears(1)]; + + yield 'yearly' => ['yearly', Carbon::now(), Carbon::now()->addYears(1)]; + + yield '1Y' => ['1Y', Carbon::now(), Carbon::now()->addYears(1)]; + + yield 'last7' => ['last7', Carbon::now(), Carbon::now()->addDays(7)]; + + yield 'last30' => ['last30', Carbon::now(), Carbon::now()->addMonthsNoOverflow(1)]; + + yield 'last90' => ['last90', Carbon::now(), Carbon::now()->addMonthsNoOverflow(3)]; + + yield 'last365' => ['last365', Carbon::now(), Carbon::now()->addYears(1)]; + + yield 'MTD' => ['MTD', Carbon::now(), Carbon::now()->addMonthsNoOverflow(1)]; + + yield 'QTD' => ['QTD', Carbon::now(), Carbon::now()->addMonthsNoOverflow(3)]; + + yield 'YTD' => ['YTD', Carbon::now(), Carbon::now()->addYears(1)]; } #[DataProvider('provideFrequencies')] @@ -141,32 +161,51 @@ final class NavigationAddPeriodTest extends TestCase self::assertSame($expected->toDateString(), $period->toDateString()); } - public static function provideFrequencies(): iterable + public static function provideFrequencies(): Iterator { - return [ - Periodicity::Daily->name => ['periodicity' => Periodicity::Daily, 'from' => Carbon::now(), 'expected' => Carbon::tomorrow()], - Periodicity::Weekly->name => ['periodicity' => Periodicity::Weekly, 'from' => Carbon::now(), 'expected' => Carbon::now()->addWeeks(1)], - Periodicity::Fortnightly->name => ['periodicity' => Periodicity::Fortnightly, 'from' => Carbon::now(), 'expected' => Carbon::now()->addWeeks(2)], - Periodicity::Monthly->name => ['periodicity' => Periodicity::Monthly, 'from' => Carbon::now(), 'expected' => Carbon::now()->addMonthsNoOverflow(1)], - '2019-01-01 to 2019-02-01' => ['periodicity' => Periodicity::Monthly, 'from' => Carbon::parse('2019-01-01'), 'expected' => Carbon::parse('2019-02-01')], - '2019-01-29 to 2019-02-28' => ['periodicity' => Periodicity::Monthly, 'from' => Carbon::parse('2019-01-29'), 'expected' => Carbon::parse('2019-02-28')], - '2019-01-30 to 2019-02-28' => ['periodicity' => Periodicity::Monthly, 'from' => Carbon::parse('2019-01-30'), 'expected' => Carbon::parse('2019-02-28')], - '2019-01-31 to 2019-02-28' => ['periodicity' => Periodicity::Monthly, 'from' => Carbon::parse('2019-01-31'), 'expected' => Carbon::parse('2019-02-28')], - '2023-03-31 to 2023-04-30' => ['periodicity' => Periodicity::Monthly, 'from' => Carbon::parse('2023-03-31'), 'expected' => Carbon::parse('2023-04-30')], - '2023-05-31 to 2023-06-30' => ['periodicity' => Periodicity::Monthly, 'from' => Carbon::parse('2023-05-31'), 'expected' => Carbon::parse('2023-06-30')], - '2023-08-31 to 2023-09-30' => ['periodicity' => Periodicity::Monthly, 'from' => Carbon::parse('2023-08-31'), 'expected' => Carbon::parse('2023-09-30')], - '2023-10-31 to 2023-11-30' => ['periodicity' => Periodicity::Monthly, 'from' => Carbon::parse('2023-10-31'), 'expected' => Carbon::parse('2023-11-30')], - Periodicity::Quarterly->name => ['periodicity' => Periodicity::Quarterly, 'from' => Carbon::now(), 'expected' => Carbon::now()->addMonthsNoOverflow(3)], - '2019-01-29 to 2020-04-29' => ['periodicity' => Periodicity::Quarterly, 'from' => Carbon::parse('2019-01-29'), 'expected' => Carbon::parse('2019-04-29')], - '2019-01-30 to 2020-04-30' => ['periodicity' => Periodicity::Quarterly, 'from' => Carbon::parse('2019-01-30'), 'expected' => Carbon::parse('2019-04-30')], - '2019-01-31 to 2020-04-30' => ['periodicity' => Periodicity::Quarterly, 'from' => Carbon::parse('2019-01-31'), 'expected' => Carbon::parse('2019-04-30')], - Periodicity::HalfYearly->name => ['periodicity' => Periodicity::HalfYearly, 'from' => Carbon::now(), 'expected' => Carbon::now()->addMonthsNoOverflow(6)], - '2019-01-31 to 2020-07-29' => ['periodicity' => Periodicity::HalfYearly, 'from' => Carbon::parse('2019-01-29'), 'expected' => Carbon::parse('2019-07-29')], - '2019-01-31 to 2020-07-30' => ['periodicity' => Periodicity::HalfYearly, 'from' => Carbon::parse('2019-01-30'), 'expected' => Carbon::parse('2019-07-30')], - '2019-01-31 to 2020-07-31' => ['periodicity' => Periodicity::HalfYearly, 'from' => Carbon::parse('2019-01-31'), 'expected' => Carbon::parse('2019-07-31')], - Periodicity::Yearly->name => ['periodicity' => Periodicity::Yearly, 'from' => Carbon::now(), 'expected' => Carbon::now()->addYears(1)], - '2020-02-29 to 2021-02-28' => ['periodicity' => Periodicity::Yearly, 'from' => Carbon::parse('2020-02-29'), 'expected' => Carbon::parse('2021-02-28')], - ]; + yield Periodicity::Daily->name => [Periodicity::Daily, Carbon::now(), Carbon::tomorrow()]; + + yield Periodicity::Weekly->name => [Periodicity::Weekly, Carbon::now(), Carbon::now()->addWeeks(1)]; + + yield Periodicity::Fortnightly->name => [Periodicity::Fortnightly, Carbon::now(), Carbon::now()->addWeeks(2)]; + + yield Periodicity::Monthly->name => [Periodicity::Monthly, Carbon::now(), Carbon::now()->addMonthsNoOverflow(1)]; + + yield '2019-01-01 to 2019-02-01' => [Periodicity::Monthly, Carbon::parse('2019-01-01'), Carbon::parse('2019-02-01')]; + + yield '2019-01-29 to 2019-02-28' => [Periodicity::Monthly, Carbon::parse('2019-01-29'), Carbon::parse('2019-02-28')]; + + yield '2019-01-30 to 2019-02-28' => [Periodicity::Monthly, Carbon::parse('2019-01-30'), Carbon::parse('2019-02-28')]; + + yield '2019-01-31 to 2019-02-28' => [Periodicity::Monthly, Carbon::parse('2019-01-31'), Carbon::parse('2019-02-28')]; + + yield '2023-03-31 to 2023-04-30' => [Periodicity::Monthly, Carbon::parse('2023-03-31'), Carbon::parse('2023-04-30')]; + + yield '2023-05-31 to 2023-06-30' => [Periodicity::Monthly, Carbon::parse('2023-05-31'), Carbon::parse('2023-06-30')]; + + yield '2023-08-31 to 2023-09-30' => [Periodicity::Monthly, Carbon::parse('2023-08-31'), Carbon::parse('2023-09-30')]; + + yield '2023-10-31 to 2023-11-30' => [Periodicity::Monthly, Carbon::parse('2023-10-31'), Carbon::parse('2023-11-30')]; + + yield Periodicity::Quarterly->name => [Periodicity::Quarterly, Carbon::now(), Carbon::now()->addMonthsNoOverflow(3)]; + + yield '2019-01-29 to 2020-04-29' => [Periodicity::Quarterly, Carbon::parse('2019-01-29'), Carbon::parse('2019-04-29')]; + + yield '2019-01-30 to 2020-04-30' => [Periodicity::Quarterly, Carbon::parse('2019-01-30'), Carbon::parse('2019-04-30')]; + + yield '2019-01-31 to 2020-04-30' => [Periodicity::Quarterly, Carbon::parse('2019-01-31'), Carbon::parse('2019-04-30')]; + + yield Periodicity::HalfYearly->name => [Periodicity::HalfYearly, Carbon::now(), Carbon::now()->addMonthsNoOverflow(6)]; + + yield '2019-01-31 to 2020-07-29' => [Periodicity::HalfYearly, Carbon::parse('2019-01-29'), Carbon::parse('2019-07-29')]; + + yield '2019-01-31 to 2020-07-30' => [Periodicity::HalfYearly, Carbon::parse('2019-01-30'), Carbon::parse('2019-07-30')]; + + yield '2019-01-31 to 2020-07-31' => [Periodicity::HalfYearly, Carbon::parse('2019-01-31'), Carbon::parse('2019-07-31')]; + + yield Periodicity::Yearly->name => [Periodicity::Yearly, Carbon::now(), Carbon::now()->addYears(1)]; + + yield '2020-02-29 to 2021-02-28' => [Periodicity::Yearly, Carbon::parse('2020-02-29'), Carbon::parse('2021-02-28')]; } #[DataProvider('provideMonthPeriods')] @@ -176,19 +215,26 @@ final class NavigationAddPeriodTest extends TestCase self::assertSame($expected->toDateString(), $period->toDateString()); } - public static function provideMonthPeriods(): iterable + public static function provideMonthPeriods(): Iterator { - return [ - '1M' => ['frequency' => '1M', 'from' => Carbon::parse('2023-06-25'), 'expected' => Carbon::parse('2023-06-25')->addMonthsNoOverflow(1)], - 'month' => ['frequency' => 'month', 'from' => Carbon::parse('2023-06-25'), 'expected' => Carbon::parse('2023-06-25')->addMonthsNoOverflow(1)], - 'monthly' => ['frequency' => 'monthly', 'from' => Carbon::parse('2023-06-25'), 'expected' => Carbon::parse('2023-06-25')->addMonthsNoOverflow(1)], - '2019-01-29 to 2019-02-28' => ['frequency' => 'monthly', 'from' => Carbon::parse('2019-01-29'), 'expected' => Carbon::parse('2019-02-28')], - '2019-01-30 to 2019-02-28' => ['frequency' => 'monthly', 'from' => Carbon::parse('2019-01-30'), 'expected' => Carbon::parse('2019-02-28')], - '2019-01-31 to 2019-02-28' => ['frequency' => 'monthly', 'from' => Carbon::parse('2019-01-31'), 'expected' => Carbon::parse('2019-02-28')], - '2023-03-31 to 2023-04-30' => ['frequency' => 'monthly', 'from' => Carbon::parse('2023-03-31'), 'expected' => Carbon::parse('2023-04-30')], - '2023-05-31 to 2023-06-30' => ['frequency' => 'monthly', 'from' => Carbon::parse('2023-05-31'), 'expected' => Carbon::parse('2023-06-30')], - '2023-08-31 to 2023-09-30' => ['frequency' => 'monthly', 'from' => Carbon::parse('2023-08-31'), 'expected' => Carbon::parse('2023-09-30')], - '2023-10-31 to 2023-11-30' => ['frequency' => 'monthly', 'from' => Carbon::parse('2023-10-31'), 'expected' => Carbon::parse('2023-11-30')], - ]; + yield '1M' => ['1M', Carbon::parse('2023-06-25'), Carbon::parse('2023-06-25')->addMonthsNoOverflow(1)]; + + yield 'month' => ['month', Carbon::parse('2023-06-25'), Carbon::parse('2023-06-25')->addMonthsNoOverflow(1)]; + + yield 'monthly' => ['monthly', Carbon::parse('2023-06-25'), Carbon::parse('2023-06-25')->addMonthsNoOverflow(1)]; + + yield '2019-01-29 to 2019-02-28' => ['monthly', Carbon::parse('2019-01-29'), Carbon::parse('2019-02-28')]; + + yield '2019-01-30 to 2019-02-28' => ['monthly', Carbon::parse('2019-01-30'), Carbon::parse('2019-02-28')]; + + yield '2019-01-31 to 2019-02-28' => ['monthly', Carbon::parse('2019-01-31'), Carbon::parse('2019-02-28')]; + + yield '2023-03-31 to 2023-04-30' => ['monthly', Carbon::parse('2023-03-31'), Carbon::parse('2023-04-30')]; + + yield '2023-05-31 to 2023-06-30' => ['monthly', Carbon::parse('2023-05-31'), Carbon::parse('2023-06-30')]; + + yield '2023-08-31 to 2023-09-30' => ['monthly', Carbon::parse('2023-08-31'), Carbon::parse('2023-09-30')]; + + yield '2023-10-31 to 2023-11-30' => ['monthly', Carbon::parse('2023-10-31'), Carbon::parse('2023-11-30')]; } } diff --git a/tests/unit/Support/NavigationEndOfPeriodTest.php b/tests/unit/Support/NavigationEndOfPeriodTest.php index 4a8e6a03bc..f76bb84be9 100644 --- a/tests/unit/Support/NavigationEndOfPeriodTest.php +++ b/tests/unit/Support/NavigationEndOfPeriodTest.php @@ -23,6 +23,8 @@ declare(strict_types=1); namespace Tests\unit\Support; +use Override; +use Iterator; use Carbon\Carbon; use FireflyIII\Support\Navigation; use Illuminate\Support\Facades\Log; @@ -42,6 +44,7 @@ final class NavigationEndOfPeriodTest extends TestCase { private Navigation $navigation; + #[Override] protected function setUp(): void { parent::setUp(); @@ -55,35 +58,56 @@ final class NavigationEndOfPeriodTest extends TestCase self::assertSame($expected->toDateString(), $period->toDateString()); } - public static function provideDates(): iterable + public static function provideDates(): Iterator { - return [ - '1D' => ['frequency' => '1D', 'from' => Carbon::now(), 'expected' => Carbon::now()->endOfDay()], - 'daily' => ['frequency' => 'daily', 'from' => Carbon::now(), 'expected' => Carbon::now()->endOfDay()], - '1W' => ['frequency' => '1W', 'from' => Carbon::now(), 'expected' => Carbon::now()->addWeek()->subDay()->endOfDay()], - 'week' => ['frequency' => 'week', 'from' => Carbon::now(), 'expected' => Carbon::now()->addWeek()->subDay()->endOfDay()], - 'weekly' => ['frequency' => 'weekly', 'from' => Carbon::now(), 'expected' => Carbon::now()->addWeek()->subDay()->endOfDay()], - 'month' => ['frequency' => 'month', 'from' => Carbon::now(), 'expected' => Carbon::now()->addMonth()->subDay()->endOfDay()], - '1M' => ['frequency' => '1M', 'from' => Carbon::now(), 'expected' => Carbon::now()->addMonth()->subDay()->endOfDay()], - 'monthly' => ['frequency' => 'monthly', 'from' => Carbon::now(), 'expected' => Carbon::now()->addMonth()->subDay()->endOfDay()], - '3M' => ['frequency' => '3M', 'from' => Carbon::now(), 'expected' => Carbon::now()->addQuarter()->subDay()->endOfDay()], - 'quarter' => ['frequency' => 'quarter', 'from' => Carbon::now(), 'expected' => Carbon::now()->addQuarter()->subDay()->endOfDay()], - 'quarterly' => ['frequency' => 'quarterly', 'from' => Carbon::now(), 'expected' => Carbon::now()->addQuarter()->subDay()->endOfDay()], - 'year' => ['frequency' => 'year', 'from' => Carbon::now(), 'expected' => Carbon::now()->addYearNoOverflow()->subDay()->endOfDay()], - 'yearly' => ['frequency' => 'yearly', 'from' => Carbon::now(), 'expected' => Carbon::now()->addYearNoOverflow()->subDay()->endOfDay()], - '1Y' => ['frequency' => '1Y', 'from' => Carbon::now(), 'expected' => Carbon::now()->addYearNoOverflow()->subDay()->endOfDay()], - 'half-year' => ['frequency' => 'half-year', 'from' => Carbon::parse('2023-05-20'), 'expected' => Carbon::parse('2023-11-19')->endOfDay()], - '6M' => ['frequency' => '6M', 'from' => Carbon::parse('2023-08-20'), 'expected' => Carbon::parse('2024-02-19')], - 'last7' => ['frequency' => 'last7', 'from' => Carbon::now(), 'expected' => Carbon::now()->addDays(7)->endOfDay()], - 'last30' => ['frequency' => 'last30', 'from' => Carbon::now(), 'expected' => Carbon::now()->addDays(30)->endOfDay()], - 'last90' => ['frequency' => 'last90', 'from' => Carbon::now(), 'expected' => Carbon::now()->addDays(90)->endOfDay()], - 'last365' => ['frequency' => 'last365', 'from' => Carbon::now(), 'expected' => Carbon::now()->addDays(365)->endOfDay()], - 'MTD' => ['frequency' => 'MTD', 'from' => Carbon::now(), - 'expected' => Carbon::now()->isSameMonth(Carbon::now()) ? Carbon::now()->endOfDay() : Carbon::now()->endOfMonth()], - 'QTD' => ['frequency' => 'QTD', 'from' => Carbon::now(), 'expected' => Carbon::now()->firstOfQuarter()->startOfDay()], - 'YTD' => ['frequency' => 'YTD', 'from' => Carbon::now(), 'expected' => Carbon::now()->firstOfYear()->startOfDay()], - 'week 2023-08-05 to 2023-08-11' => ['frequency' => '1W', 'from' => Carbon::parse('2023-08-05'), 'expected' => Carbon::parse('2023-08-11')->endOfDay()], - ]; + yield '1D' => ['1D', Carbon::now(), Carbon::now()->endOfDay()]; + + yield 'daily' => ['daily', Carbon::now(), Carbon::now()->endOfDay()]; + + yield '1W' => ['1W', Carbon::now(), Carbon::now()->addWeek()->subDay()->endOfDay()]; + + yield 'week' => ['week', Carbon::now(), Carbon::now()->addWeek()->subDay()->endOfDay()]; + + yield 'weekly' => ['weekly', Carbon::now(), Carbon::now()->addWeek()->subDay()->endOfDay()]; + + yield 'month' => ['month', Carbon::now(), Carbon::now()->addMonth()->subDay()->endOfDay()]; + + yield '1M' => ['1M', Carbon::now(), Carbon::now()->addMonth()->subDay()->endOfDay()]; + + yield 'monthly' => ['monthly', Carbon::now(), Carbon::now()->addMonth()->subDay()->endOfDay()]; + + yield '3M' => ['3M', Carbon::now(), Carbon::now()->addQuarter()->subDay()->endOfDay()]; + + yield 'quarter' => ['quarter', Carbon::now(), Carbon::now()->addQuarter()->subDay()->endOfDay()]; + + yield 'quarterly' => ['quarterly', Carbon::now(), Carbon::now()->addQuarter()->subDay()->endOfDay()]; + + yield 'year' => ['year', Carbon::now(), Carbon::now()->addYearNoOverflow()->subDay()->endOfDay()]; + + yield 'yearly' => ['yearly', Carbon::now(), Carbon::now()->addYearNoOverflow()->subDay()->endOfDay()]; + + yield '1Y' => ['1Y', Carbon::now(), Carbon::now()->addYearNoOverflow()->subDay()->endOfDay()]; + + yield 'half-year' => ['half-year', Carbon::parse('2023-05-20'), Carbon::parse('2023-11-19')->endOfDay()]; + + yield '6M' => ['6M', Carbon::parse('2023-08-20'), Carbon::parse('2024-02-19')]; + + yield 'last7' => ['last7', Carbon::now(), Carbon::now()->addDays(7)->endOfDay()]; + + yield 'last30' => ['last30', Carbon::now(), Carbon::now()->addDays(30)->endOfDay()]; + + yield 'last90' => ['last90', Carbon::now(), Carbon::now()->addDays(90)->endOfDay()]; + + yield 'last365' => ['last365', Carbon::now(), Carbon::now()->addDays(365)->endOfDay()]; + + yield 'MTD' => ['MTD', Carbon::now(), + Carbon::now()->isSameMonth(Carbon::now()) ? Carbon::now()->endOfDay() : Carbon::now()->endOfMonth()]; + + yield 'QTD' => ['QTD', Carbon::now(), Carbon::now()->firstOfQuarter()->startOfDay()]; + + yield 'YTD' => ['YTD', Carbon::now(), Carbon::now()->firstOfYear()->startOfDay()]; + + yield 'week 2023-08-05 to 2023-08-11' => ['1W', Carbon::parse('2023-08-05'), Carbon::parse('2023-08-11')->endOfDay()]; } #[DataProvider('provideUnknownFrequencies')] @@ -98,12 +122,12 @@ final class NavigationEndOfPeriodTest extends TestCase Log::shouldHaveReceived('error', [$expectedMessage]); } - public static function provideUnknownFrequencies(): iterable + public static function provideUnknownFrequencies(): Iterator { - return [ - '1day' => ['frequency' => '1day', 'from' => Carbon::now(), 'expected' => Carbon::now()], - 'unknown' => ['frequency' => 'unknown', 'from' => Carbon::now(), 'expected' => Carbon::now()->startOfDay()], - 'empty' => ['frequency' => '', 'from' => Carbon::now(), 'expected' => Carbon::now()->startOfDay()], - ]; + yield '1day' => ['1day', Carbon::now(), Carbon::now()]; + + yield 'unknown' => ['unknown', Carbon::now(), Carbon::now()->startOfDay()]; + + yield 'empty' => ['', Carbon::now(), Carbon::now()->startOfDay()]; } } diff --git a/tests/unit/Support/NavigationPreferredCarbonFormatByPeriodTest.php b/tests/unit/Support/NavigationPreferredCarbonFormatByPeriodTest.php index 166a68b37b..6f25d44beb 100644 --- a/tests/unit/Support/NavigationPreferredCarbonFormatByPeriodTest.php +++ b/tests/unit/Support/NavigationPreferredCarbonFormatByPeriodTest.php @@ -24,6 +24,8 @@ declare(strict_types=1); namespace Tests\unit\Support; +use Override; +use Iterator; use FireflyIII\Support\Navigation; use PHPUnit\Framework\Attributes\DataProvider; use Tests\integration\TestCase; @@ -41,6 +43,7 @@ final class NavigationPreferredCarbonFormatByPeriodTest extends TestCase { private Navigation $navigation; + #[Override] protected function setUp(): void { parent::setUp(); @@ -54,15 +57,18 @@ final class NavigationPreferredCarbonFormatByPeriodTest extends TestCase self::assertSame($expected, $formatPeriod); } - public static function providePeriods(): iterable + public static function providePeriods(): Iterator { - return [ - 'unknown' => ['period' => '1day', 'expected' => 'Y-m-d'], - 'week' => ['period' => '1W', 'expected' => '\WW,Y'], - 'month' => ['period' => '1M', 'expected' => 'Y-m'], - 'quarterly' => ['period' => '3M', 'expected' => '\QQ,Y'], - 'half-yearly' => ['period' => '6M', 'expected' => '\QQ,Y'], - 'yearly' => ['period' => '1Y', 'expected' => 'Y'], - ]; + yield 'unknown' => ['1day', 'Y-m-d']; + + yield 'week' => ['1W', '\WW,Y']; + + yield 'month' => ['1M', 'Y-m']; + + yield 'quarterly' => ['3M', '\QQ,Y']; + + yield 'half-yearly' => ['6M', '\QQ,Y']; + + yield 'yearly' => ['1Y', 'Y']; } } diff --git a/tests/unit/Support/NavigationPreferredCarbonFormatTest.php b/tests/unit/Support/NavigationPreferredCarbonFormatTest.php index b0a08cec13..01f06aad2b 100644 --- a/tests/unit/Support/NavigationPreferredCarbonFormatTest.php +++ b/tests/unit/Support/NavigationPreferredCarbonFormatTest.php @@ -24,6 +24,8 @@ declare(strict_types=1); namespace Tests\unit\Support; +use Override; +use Iterator; use Carbon\Carbon; use FireflyIII\Support\Navigation; use PHPUnit\Framework\Attributes\DataProvider; @@ -42,6 +44,7 @@ final class NavigationPreferredCarbonFormatTest extends TestCase { private Navigation $navigation; + #[Override] protected function setUp(): void { parent::setUp(); @@ -55,21 +58,30 @@ final class NavigationPreferredCarbonFormatTest extends TestCase self::assertSame($expected, $carbonFormat); } - public static function providePeriods(): iterable + public static function providePeriods(): Iterator { - return [ - '1 week' => ['start' => Carbon::now(), 'end' => Carbon::now()->addWeek(), 'expected' => 'Y-m-d'], - '1 month' => ['start' => Carbon::now(), 'end' => Carbon::now()->addMonth(), 'expected' => 'Y-m-d'], - '2 months' => ['start' => Carbon::now(), 'end' => Carbon::now()->addMonths(2), 'expected' => 'Y-m'], - '3 months' => ['start' => Carbon::now(), 'end' => Carbon::now()->addMonths(3), 'expected' => 'Y-m'], - '6 months' => ['start' => Carbon::now(), 'end' => Carbon::now()->addMonths(6), 'expected' => 'Y-m'], - '7 months' => ['start' => Carbon::now(), 'end' => Carbon::now()->addMonths(7), 'expected' => 'Y-m'], - '11 months' => ['start' => Carbon::now(), 'end' => Carbon::now()->addMonths(11), 'expected' => 'Y-m'], - '12 months' => ['start' => Carbon::now(), 'end' => Carbon::now()->addMonths(12), 'expected' => 'Y-m'], - '13 months' => ['start' => Carbon::now(), 'end' => Carbon::now()->addMonths(13), 'expected' => 'Y'], - '16 months' => ['start' => Carbon::now(), 'end' => Carbon::now()->addMonths(16), 'expected' => 'Y'], - '1 year' => ['start' => Carbon::now(), 'end' => Carbon::now()->addYear(), 'expected' => 'Y-m'], - '2 years' => ['start' => Carbon::now(), 'end' => Carbon::now()->addYears(2), 'expected' => 'Y'], - ]; + yield '1 week' => [Carbon::now(), Carbon::now()->addWeek(), 'Y-m-d']; + + yield '1 month' => [Carbon::now(), Carbon::now()->addMonth(), 'Y-m-d']; + + yield '2 months' => [Carbon::now(), Carbon::now()->addMonths(2), 'Y-m']; + + yield '3 months' => [Carbon::now(), Carbon::now()->addMonths(3), 'Y-m']; + + yield '6 months' => [Carbon::now(), Carbon::now()->addMonths(6), 'Y-m']; + + yield '7 months' => [Carbon::now(), Carbon::now()->addMonths(7), 'Y-m']; + + yield '11 months' => [Carbon::now(), Carbon::now()->addMonths(11), 'Y-m']; + + yield '12 months' => [Carbon::now(), Carbon::now()->addMonths(12), 'Y-m']; + + yield '13 months' => [Carbon::now(), Carbon::now()->addMonths(13), 'Y']; + + yield '16 months' => [Carbon::now(), Carbon::now()->addMonths(16), 'Y']; + + yield '1 year' => [Carbon::now(), Carbon::now()->addYear(), 'Y-m']; + + yield '2 years' => [Carbon::now(), Carbon::now()->addYears(2), 'Y']; } } diff --git a/tests/unit/Support/NavigationPreferredEndOfPeriodTest.php b/tests/unit/Support/NavigationPreferredEndOfPeriodTest.php index 74b4b091c8..95bf81b575 100644 --- a/tests/unit/Support/NavigationPreferredEndOfPeriodTest.php +++ b/tests/unit/Support/NavigationPreferredEndOfPeriodTest.php @@ -24,6 +24,8 @@ declare(strict_types=1); namespace Tests\unit\Support; +use Override; +use Iterator; use Carbon\Carbon; use FireflyIII\Support\Navigation; use PHPUnit\Framework\Attributes\DataProvider; @@ -42,6 +44,7 @@ final class NavigationPreferredEndOfPeriodTest extends TestCase { private Navigation $navigation; + #[Override] protected function setUp(): void { parent::setUp(); @@ -55,21 +58,30 @@ final class NavigationPreferredEndOfPeriodTest extends TestCase self::assertSame($expected, $formatPeriod); } - public static function providePeriods(): iterable + public static function providePeriods(): Iterator { - return [ - '1 week' => ['start' => Carbon::now(), 'end' => Carbon::now()->addWeek(), 'expected' => 'endOfDay'], - '1 month' => ['start' => Carbon::now(), 'end' => Carbon::now()->addMonth(), 'expected' => 'endOfDay'], - '2 months' => ['start' => Carbon::now(), 'end' => Carbon::now()->addMonths(2), 'expected' => 'endOfMonth'], - '3 months' => ['start' => Carbon::now(), 'end' => Carbon::now()->addMonths(3), 'expected' => 'endOfMonth'], - '6 months' => ['start' => Carbon::now(), 'end' => Carbon::now()->addMonths(6), 'expected' => 'endOfMonth'], - '7 months' => ['start' => Carbon::now(), 'end' => Carbon::now()->addMonths(7), 'expected' => 'endOfMonth'], - '11 months' => ['start' => Carbon::now(), 'end' => Carbon::now()->addMonths(11), 'expected' => 'endOfMonth'], - '12 months' => ['start' => Carbon::now(), 'end' => Carbon::now()->addMonths(12), 'expected' => 'endOfMonth'], - '13 months' => ['start' => Carbon::now(), 'end' => Carbon::now()->addMonths(13), 'expected' => 'endOfYear'], - '16 months' => ['start' => Carbon::now(), 'end' => Carbon::now()->addMonths(16), 'expected' => 'endOfYear'], - '1 year' => ['start' => Carbon::now(), 'end' => Carbon::now()->addYear(), 'expected' => 'endOfMonth'], - '2 years' => ['start' => Carbon::now(), 'end' => Carbon::now()->addYears(2), 'expected' => 'endOfYear'], - ]; + yield '1 week' => [Carbon::now(), Carbon::now()->addWeek(), 'endOfDay']; + + yield '1 month' => [Carbon::now(), Carbon::now()->addMonth(), 'endOfDay']; + + yield '2 months' => [Carbon::now(), Carbon::now()->addMonths(2), 'endOfMonth']; + + yield '3 months' => [Carbon::now(), Carbon::now()->addMonths(3), 'endOfMonth']; + + yield '6 months' => [Carbon::now(), Carbon::now()->addMonths(6), 'endOfMonth']; + + yield '7 months' => [Carbon::now(), Carbon::now()->addMonths(7), 'endOfMonth']; + + yield '11 months' => [Carbon::now(), Carbon::now()->addMonths(11), 'endOfMonth']; + + yield '12 months' => [Carbon::now(), Carbon::now()->addMonths(12), 'endOfMonth']; + + yield '13 months' => [Carbon::now(), Carbon::now()->addMonths(13), 'endOfYear']; + + yield '16 months' => [Carbon::now(), Carbon::now()->addMonths(16), 'endOfYear']; + + yield '1 year' => [Carbon::now(), Carbon::now()->addYear(), 'endOfMonth']; + + yield '2 years' => [Carbon::now(), Carbon::now()->addYears(2), 'endOfYear']; } } diff --git a/tests/unit/Support/NavigationPreferredRangeFormatTest.php b/tests/unit/Support/NavigationPreferredRangeFormatTest.php index daae6b3731..6c0eff7d07 100644 --- a/tests/unit/Support/NavigationPreferredRangeFormatTest.php +++ b/tests/unit/Support/NavigationPreferredRangeFormatTest.php @@ -24,6 +24,8 @@ declare(strict_types=1); namespace Tests\unit\Support; +use Override; +use Iterator; use Carbon\Carbon; use FireflyIII\Support\Navigation; use PHPUnit\Framework\Attributes\DataProvider; @@ -42,6 +44,7 @@ final class NavigationPreferredRangeFormatTest extends TestCase { private Navigation $navigation; + #[Override] protected function setUp(): void { parent::setUp(); @@ -55,21 +58,30 @@ final class NavigationPreferredRangeFormatTest extends TestCase self::assertSame($expected, $formatPeriod); } - public static function providePeriods(): iterable + public static function providePeriods(): Iterator { - return [ - '1 week' => ['start' => Carbon::now(), 'end' => Carbon::now()->addWeek(), 'expected' => '1D'], - '1 month' => ['start' => Carbon::now(), 'end' => Carbon::now()->addMonth(), 'expected' => '1D'], - '2 months' => ['start' => Carbon::now(), 'end' => Carbon::now()->addMonths(2), 'expected' => '1M'], - '3 months' => ['start' => Carbon::now(), 'end' => Carbon::now()->addMonths(3), 'expected' => '1M'], - '6 months' => ['start' => Carbon::now(), 'end' => Carbon::now()->addMonths(6), 'expected' => '1M'], - '7 months' => ['start' => Carbon::now(), 'end' => Carbon::now()->addMonths(7), 'expected' => '1M'], - '11 months' => ['start' => Carbon::now(), 'end' => Carbon::now()->addMonths(11), 'expected' => '1M'], - '12 months' => ['start' => Carbon::now(), 'end' => Carbon::now()->addMonths(12), 'expected' => '1M'], - '13 months' => ['start' => Carbon::now(), 'end' => Carbon::now()->addMonths(13), 'expected' => '1Y'], - '16 months' => ['start' => Carbon::now(), 'end' => Carbon::now()->addMonths(16), 'expected' => '1Y'], - '1 year' => ['start' => Carbon::now(), 'end' => Carbon::now()->addYear(), 'expected' => '1M'], - '2 years' => ['start' => Carbon::now(), 'end' => Carbon::now()->addYears(2), 'expected' => '1Y'], - ]; + yield '1 week' => [Carbon::now(), Carbon::now()->addWeek(), '1D']; + + yield '1 month' => [Carbon::now(), Carbon::now()->addMonth(), '1D']; + + yield '2 months' => [Carbon::now(), Carbon::now()->addMonths(2), '1M']; + + yield '3 months' => [Carbon::now(), Carbon::now()->addMonths(3), '1M']; + + yield '6 months' => [Carbon::now(), Carbon::now()->addMonths(6), '1M']; + + yield '7 months' => [Carbon::now(), Carbon::now()->addMonths(7), '1M']; + + yield '11 months' => [Carbon::now(), Carbon::now()->addMonths(11), '1M']; + + yield '12 months' => [Carbon::now(), Carbon::now()->addMonths(12), '1M']; + + yield '13 months' => [Carbon::now(), Carbon::now()->addMonths(13), '1Y']; + + yield '16 months' => [Carbon::now(), Carbon::now()->addMonths(16), '1Y']; + + yield '1 year' => [Carbon::now(), Carbon::now()->addYear(), '1M']; + + yield '2 years' => [Carbon::now(), Carbon::now()->addYears(2), '1Y']; } } diff --git a/tests/unit/Support/NavigationPreferredSqlFormatTest.php b/tests/unit/Support/NavigationPreferredSqlFormatTest.php index 4bf135cf2a..fa44b76178 100644 --- a/tests/unit/Support/NavigationPreferredSqlFormatTest.php +++ b/tests/unit/Support/NavigationPreferredSqlFormatTest.php @@ -24,6 +24,8 @@ declare(strict_types=1); namespace Tests\unit\Support; +use Override; +use Iterator; use Carbon\Carbon; use FireflyIII\Support\Navigation; use PHPUnit\Framework\Attributes\DataProvider; @@ -42,6 +44,7 @@ final class NavigationPreferredSqlFormatTest extends TestCase { private Navigation $navigation; + #[Override] protected function setUp(): void { parent::setUp(); @@ -55,21 +58,30 @@ final class NavigationPreferredSqlFormatTest extends TestCase self::assertSame($expected, $formatPeriod); } - public static function provideDates(): iterable + public static function provideDates(): Iterator { - return [ - '1 week' => ['start' => Carbon::now(), 'end' => Carbon::now()->addWeek(), 'expected' => '%Y-%m-%d'], - '1 month' => ['start' => Carbon::now(), 'end' => Carbon::now()->addMonth(), 'expected' => '%Y-%m-%d'], - '2 months' => ['start' => Carbon::now(), 'end' => Carbon::now()->addMonths(2), 'expected' => '%Y-%m'], - '3 months' => ['start' => Carbon::now(), 'end' => Carbon::now()->addMonths(3), 'expected' => '%Y-%m'], - '6 months' => ['start' => Carbon::now(), 'end' => Carbon::now()->addMonths(6), 'expected' => '%Y-%m'], - '7 months' => ['start' => Carbon::now(), 'end' => Carbon::now()->addMonths(7), 'expected' => '%Y-%m'], - '11 months' => ['start' => Carbon::now(), 'end' => Carbon::now()->addMonths(11), 'expected' => '%Y-%m'], - '12 months' => ['start' => Carbon::now(), 'end' => Carbon::now()->addMonths(12), 'expected' => '%Y-%m'], - '13 months' => ['start' => Carbon::now(), 'end' => Carbon::now()->addMonths(13), 'expected' => '%Y'], - '16 months' => ['start' => Carbon::now(), 'end' => Carbon::now()->addMonths(16), 'expected' => '%Y'], - '1 year' => ['start' => Carbon::now(), 'end' => Carbon::now()->addYear(), 'expected' => '%Y-%m'], - '2 years' => ['start' => Carbon::now(), 'end' => Carbon::now()->addYears(2), 'expected' => '%Y'], - ]; + yield '1 week' => [Carbon::now(), Carbon::now()->addWeek(), '%Y-%m-%d']; + + yield '1 month' => [Carbon::now(), Carbon::now()->addMonth(), '%Y-%m-%d']; + + yield '2 months' => [Carbon::now(), Carbon::now()->addMonths(2), '%Y-%m']; + + yield '3 months' => [Carbon::now(), Carbon::now()->addMonths(3), '%Y-%m']; + + yield '6 months' => [Carbon::now(), Carbon::now()->addMonths(6), '%Y-%m']; + + yield '7 months' => [Carbon::now(), Carbon::now()->addMonths(7), '%Y-%m']; + + yield '11 months' => [Carbon::now(), Carbon::now()->addMonths(11), '%Y-%m']; + + yield '12 months' => [Carbon::now(), Carbon::now()->addMonths(12), '%Y-%m']; + + yield '13 months' => [Carbon::now(), Carbon::now()->addMonths(13), '%Y']; + + yield '16 months' => [Carbon::now(), Carbon::now()->addMonths(16), '%Y']; + + yield '1 year' => [Carbon::now(), Carbon::now()->addYear(), '%Y-%m']; + + yield '2 years' => [Carbon::now(), Carbon::now()->addYears(2), '%Y']; } } diff --git a/tests/unit/Support/NavigationStartOfPeriodTest.php b/tests/unit/Support/NavigationStartOfPeriodTest.php index c037fa3f10..ffe2514683 100644 --- a/tests/unit/Support/NavigationStartOfPeriodTest.php +++ b/tests/unit/Support/NavigationStartOfPeriodTest.php @@ -24,6 +24,8 @@ declare(strict_types=1); namespace Tests\unit\Support; +use Override; +use Iterator; use Carbon\Carbon; use FireflyIII\Support\Navigation; use Illuminate\Support\Facades\Log; @@ -43,6 +45,7 @@ final class NavigationStartOfPeriodTest extends TestCase { private Navigation $navigation; + #[Override] protected function setUp(): void { parent::setUp(); @@ -56,34 +59,55 @@ final class NavigationStartOfPeriodTest extends TestCase self::assertSame($expected->toDateString(), $period->toDateString()); } - public static function provideDates(): iterable + public static function provideDates(): Iterator { - return [ - 'custom' => ['frequency' => 'custom', 'from' => Carbon::now(), 'expected' => Carbon::now()], - '1D' => ['frequency' => '1D', 'from' => Carbon::now(), 'expected' => Carbon::now()->startOfDay()], - 'daily' => ['frequency' => 'daily', 'from' => Carbon::now(), 'expected' => Carbon::now()->startOfDay()], - '1W' => ['frequency' => '1W', 'from' => Carbon::now(), 'expected' => Carbon::now()->startOfWeek()], - 'week' => ['frequency' => 'week', 'from' => Carbon::now(), 'expected' => Carbon::now()->startOfWeek()], - 'weekly' => ['frequency' => 'weekly', 'from' => Carbon::now(), 'expected' => Carbon::now()->startOfWeek()], - 'month' => ['frequency' => 'month', 'from' => Carbon::now(), 'expected' => Carbon::now()->startOfMonth()], - '1M' => ['frequency' => '1M', 'from' => Carbon::now(), 'expected' => Carbon::now()->startOfMonth()], - 'monthly' => ['frequency' => 'monthly', 'from' => Carbon::now(), 'expected' => Carbon::now()->startOfMonth()], - '3M' => ['frequency' => '3M', 'from' => Carbon::now(), 'expected' => Carbon::now()->firstOfQuarter()], - 'quarter' => ['frequency' => 'quarter', 'from' => Carbon::now(), 'expected' => Carbon::now()->firstOfQuarter()], - 'quarterly' => ['frequency' => 'quarterly', 'from' => Carbon::now(), 'expected' => Carbon::now()->firstOfQuarter()], - 'year' => ['frequency' => 'year', 'from' => Carbon::now(), 'expected' => Carbon::now()->startOfYear()], - 'yearly' => ['frequency' => 'yearly', 'from' => Carbon::now(), 'expected' => Carbon::now()->startOfYear()], - '1Y' => ['frequency' => '1Y', 'from' => Carbon::now(), 'expected' => Carbon::now()->startOfYear()], - 'half-year' => ['frequency' => 'half-year', 'from' => Carbon::parse('2023-05-20'), 'expected' => Carbon::parse('2023-01-01')->startOfYear()], - '6M' => ['frequency' => '6M', 'from' => Carbon::parse('2023-08-20'), 'expected' => Carbon::parse('2023-07-01')], - 'last7' => ['frequency' => 'last7', 'from' => Carbon::now(), 'expected' => Carbon::now()->subDays(7)->startOfDay()], - 'last30' => ['frequency' => 'last30', 'from' => Carbon::now(), 'expected' => Carbon::now()->subDays(30)->startOfDay()], - 'last90' => ['frequency' => 'last90', 'from' => Carbon::now(), 'expected' => Carbon::now()->subDays(90)->startOfDay()], - 'last365' => ['frequency' => 'last365', 'from' => Carbon::now(), 'expected' => Carbon::now()->subDays(365)->startOfDay()], - 'MTD' => ['frequency' => 'MTD', 'from' => Carbon::now(), 'expected' => Carbon::now()->startOfMonth()->startOfDay()], - 'QTD' => ['frequency' => 'QTD', 'from' => Carbon::now(), 'expected' => Carbon::now()->firstOfQuarter()->startOfDay()], - 'YTD' => ['frequency' => 'YTD', 'from' => Carbon::now(), 'expected' => Carbon::now()->startOfYear()->startOfDay()], - ]; + yield 'custom' => ['custom', Carbon::now(), Carbon::now()]; + + yield '1D' => ['1D', Carbon::now(), Carbon::now()->startOfDay()]; + + yield 'daily' => ['daily', Carbon::now(), Carbon::now()->startOfDay()]; + + yield '1W' => ['1W', Carbon::now(), Carbon::now()->startOfWeek()]; + + yield 'week' => ['week', Carbon::now(), Carbon::now()->startOfWeek()]; + + yield 'weekly' => ['weekly', Carbon::now(), Carbon::now()->startOfWeek()]; + + yield 'month' => ['month', Carbon::now(), Carbon::now()->startOfMonth()]; + + yield '1M' => ['1M', Carbon::now(), Carbon::now()->startOfMonth()]; + + yield 'monthly' => ['monthly', Carbon::now(), Carbon::now()->startOfMonth()]; + + yield '3M' => ['3M', Carbon::now(), Carbon::now()->firstOfQuarter()]; + + yield 'quarter' => ['quarter', Carbon::now(), Carbon::now()->firstOfQuarter()]; + + yield 'quarterly' => ['quarterly', Carbon::now(), Carbon::now()->firstOfQuarter()]; + + yield 'year' => ['year', Carbon::now(), Carbon::now()->startOfYear()]; + + yield 'yearly' => ['yearly', Carbon::now(), Carbon::now()->startOfYear()]; + + yield '1Y' => ['1Y', Carbon::now(), Carbon::now()->startOfYear()]; + + yield 'half-year' => ['half-year', Carbon::parse('2023-05-20'), Carbon::parse('2023-01-01')->startOfYear()]; + + yield '6M' => ['6M', Carbon::parse('2023-08-20'), Carbon::parse('2023-07-01')]; + + yield 'last7' => ['last7', Carbon::now(), Carbon::now()->subDays(7)->startOfDay()]; + + yield 'last30' => ['last30', Carbon::now(), Carbon::now()->subDays(30)->startOfDay()]; + + yield 'last90' => ['last90', Carbon::now(), Carbon::now()->subDays(90)->startOfDay()]; + + yield 'last365' => ['last365', Carbon::now(), Carbon::now()->subDays(365)->startOfDay()]; + + yield 'MTD' => ['MTD', Carbon::now(), Carbon::now()->startOfMonth()->startOfDay()]; + + yield 'QTD' => ['QTD', Carbon::now(), Carbon::now()->firstOfQuarter()->startOfDay()]; + + yield 'YTD' => ['YTD', Carbon::now(), Carbon::now()->startOfYear()->startOfDay()]; } #[DataProvider('provideUnknownFrequencies')] @@ -100,12 +124,12 @@ final class NavigationStartOfPeriodTest extends TestCase self::assertSame($expected->toDateString(), $period->toDateString()); } - public static function provideUnknownFrequencies(): iterable + public static function provideUnknownFrequencies(): Iterator { - return [ - '1day' => ['frequency' => '1day', 'from' => Carbon::now(), 'expected' => Carbon::now()], - 'unknown' => ['frequency' => 'unknown', 'from' => Carbon::now(), 'expected' => Carbon::now()->startOfDay()], - 'empty' => ['frequency' => '', 'from' => Carbon::now(), 'expected' => Carbon::now()->startOfDay()], - ]; + yield '1day' => ['1day', Carbon::now(), Carbon::now()]; + + yield 'unknown' => ['unknown', Carbon::now(), Carbon::now()->startOfDay()]; + + yield 'empty' => ['', Carbon::now(), Carbon::now()->startOfDay()]; } } diff --git a/tests/unit/Support/Search/QueryParser/AbstractQueryParserInterfaceParseQueryTester.php b/tests/unit/Support/Search/QueryParser/AbstractQueryParserInterfaceParseQueryTester.php index 780f00d113..311e745586 100644 --- a/tests/unit/Support/Search/QueryParser/AbstractQueryParserInterfaceParseQueryTester.php +++ b/tests/unit/Support/Search/QueryParser/AbstractQueryParserInterfaceParseQueryTester.php @@ -4,6 +4,7 @@ declare(strict_types=1); namespace Tests\unit\Support\Search\QueryParser; +use Iterator; use FireflyIII\Support\Search\QueryParser\FieldNode; use FireflyIII\Support\Search\QueryParser\QueryParserInterface; use FireflyIII\Support\Search\QueryParser\StringNode; @@ -29,170 +30,190 @@ abstract class AbstractQueryParserInterfaceParseQueryTester extends TestCase } - public static function queryDataProvider(): iterable + public static function queryDataProvider(): Iterator { - return [ - 'empty query' => [ - 'query' => '', - 'expected' => new NodeGroup([]), - ], - 'simple word' => [ - 'query' => 'groceries', - 'expected' => new NodeGroup([new StringNode('groceries')]), - ], - 'prohibited word' => [ - 'query' => '-groceries', - 'expected' => new NodeGroup([new StringNode('groceries', true)]), - ], - 'prohibited field' => [ - 'query' => '-amount:100', - 'expected' => new NodeGroup([new FieldNode('amount', '100', true)]), - ], - 'quoted word' => [ - 'query' => '"test phrase"', - 'expected' => new NodeGroup([new StringNode('test phrase')]), - ], - 'prohibited quoted word' => [ - 'query' => '-"test phrase"', - 'expected' => new NodeGroup([new StringNode('test phrase', true)]), - ], - 'multiple words' => [ - 'query' => 'groceries shopping market', - 'expected' => new NodeGroup([ - new StringNode('groceries'), - new StringNode('shopping'), - new StringNode('market'), - ]), - ], - 'field operator' => [ - 'query' => 'amount:100', - 'expected' => new NodeGroup([new FieldNode('amount', '100')]), - ], - 'quoted field value with single space' => [ - 'query' => 'description:"test phrase"', - 'expected' => new NodeGroup([new FieldNode('description', 'test phrase')]), - ], - 'multiple fields' => [ - 'query' => 'amount:100 category:food', - 'expected' => new NodeGroup([ + yield 'empty query' => [ + '', + new NodeGroup([]), + ]; + + yield 'simple word' => [ + 'groceries', + new NodeGroup([new StringNode('groceries')]), + ]; + + yield 'prohibited word' => [ + '-groceries', + new NodeGroup([new StringNode('groceries', true)]), + ]; + + yield 'prohibited field' => [ + '-amount:100', + new NodeGroup([new FieldNode('amount', '100', true)]), + ]; + + yield 'quoted word' => [ + '"test phrase"', + new NodeGroup([new StringNode('test phrase')]), + ]; + + yield 'prohibited quoted word' => [ + '-"test phrase"', + new NodeGroup([new StringNode('test phrase', true)]), + ]; + + yield 'multiple words' => [ + 'groceries shopping market', + new NodeGroup([ + new StringNode('groceries'), + new StringNode('shopping'), + new StringNode('market'), + ]), + ]; + + yield 'field operator' => [ + 'amount:100', + new NodeGroup([new FieldNode('amount', '100')]), + ]; + + yield 'quoted field value with single space' => [ + 'description:"test phrase"', + new NodeGroup([new FieldNode('description', 'test phrase')]), + ]; + + yield 'multiple fields' => [ + 'amount:100 category:food', + new NodeGroup([ + new FieldNode('amount', '100'), + new FieldNode('category', 'food'), + ]), + ]; + + yield 'simple subquery' => [ + '(amount:100 category:food)', + new NodeGroup([ + new NodeGroup([ new FieldNode('amount', '100'), new FieldNode('category', 'food'), ]), - ], - 'simple subquery' => [ - 'query' => '(amount:100 category:food)', - 'expected' => new NodeGroup([ - new NodeGroup([ - new FieldNode('amount', '100'), - new FieldNode('category', 'food'), - ]), - ]), - ], - 'prohibited subquery' => [ - 'query' => '-(amount:100 category:food)', - 'expected' => new NodeGroup([ - new NodeGroup([ - new FieldNode('amount', '100'), - new FieldNode('category', 'food'), - ], true), - ]), - ], - 'nested subquery' => [ - 'query' => '(amount:100 (description:"test" category:food))', - 'expected' => new NodeGroup([ - new NodeGroup([ - new FieldNode('amount', '100'), - new NodeGroup([ - new FieldNode('description', 'test'), - new FieldNode('category', 'food'), - ]), - ]), - ]), - ], - 'mixed words and operators' => [ - 'query' => 'groceries amount:50 shopping', - 'expected' => new NodeGroup([ - new StringNode('groceries'), - new FieldNode('amount', '50'), - new StringNode('shopping'), - ]), - ], - 'subquery after field value' => [ - 'query' => 'amount:100 (description:"market" category:food)', - 'expected' => new NodeGroup([ + ]), + ]; + + yield 'prohibited subquery' => [ + '-(amount:100 category:food)', + new NodeGroup([ + new NodeGroup([ + new FieldNode('amount', '100'), + new FieldNode('category', 'food'), + ], true), + ]), + ]; + + yield 'nested subquery' => [ + '(amount:100 (description:"test" category:food))', + new NodeGroup([ + new NodeGroup([ new FieldNode('amount', '100'), new NodeGroup([ - new FieldNode('description', 'market'), + new FieldNode('description', 'test'), new FieldNode('category', 'food'), ]), ]), - ], - 'word followed by subquery' => [ - 'query' => 'groceries (amount:100 description_contains:"test")', - 'expected' => new NodeGroup([ - new StringNode('groceries'), + ]), + ]; + + yield 'mixed words and operators' => [ + 'groceries amount:50 shopping', + new NodeGroup([ + new StringNode('groceries'), + new FieldNode('amount', '50'), + new StringNode('shopping'), + ]), + ]; + + yield 'subquery after field value' => [ + 'amount:100 (description:"market" category:food)', + new NodeGroup([ + new FieldNode('amount', '100'), + new NodeGroup([ + new FieldNode('description', 'market'), + new FieldNode('category', 'food'), + ]), + ]), + ]; + + yield 'word followed by subquery' => [ + 'groceries (amount:100 description_contains:"test")', + new NodeGroup([ + new StringNode('groceries'), + new NodeGroup([ + new FieldNode('amount', '100'), + new FieldNode('description_contains', 'test'), + ]), + ]), + ]; + + yield 'nested subquery with prohibited field' => [ + '(amount:100 (description_contains:"test payment" -has_attachments:true))', + new NodeGroup([ + new NodeGroup([ + new FieldNode('amount', '100'), new NodeGroup([ - new FieldNode('amount', '100'), - new FieldNode('description_contains', 'test'), + new FieldNode('description_contains', 'test payment'), + new FieldNode('has_attachments', 'true', true), ]), ]), - ], - 'nested subquery with prohibited field' => [ - 'query' => '(amount:100 (description_contains:"test payment" -has_attachments:true))', - 'expected' => new NodeGroup([ + ]), + ]; + + yield 'complex nested subqueries' => [ + 'shopping (amount:50 market (-category:food word description:"test phrase" (has_notes:true)))', + new NodeGroup([ + new StringNode('shopping'), + new NodeGroup([ + new FieldNode('amount', '50'), + new StringNode('market'), new NodeGroup([ - new FieldNode('amount', '100'), + new FieldNode('category', 'food', true), + new StringNode('word'), + new FieldNode('description', 'test phrase'), new NodeGroup([ - new FieldNode('description_contains', 'test payment'), - new FieldNode('has_attachments', 'true', true), + new FieldNode('has_notes', 'true'), ]), ]), ]), - ], - 'complex nested subqueries' => [ - 'query' => 'shopping (amount:50 market (-category:food word description:"test phrase" (has_notes:true)))', - 'expected' => new NodeGroup([ - new StringNode('shopping'), - new NodeGroup([ - new FieldNode('amount', '50'), - new StringNode('market'), - new NodeGroup([ - new FieldNode('category', 'food', true), - new StringNode('word'), - new FieldNode('description', 'test phrase'), - new NodeGroup([ - new FieldNode('has_notes', 'true'), - ]), - ]), - ]), + ]), + ]; + + yield 'word with multiple spaces' => [ + '"multiple spaces"', + new NodeGroup([new StringNode('multiple spaces')]), + ]; + + yield 'field with multiple spaces in value' => [ + 'description:"multiple spaces here"', + new NodeGroup([new FieldNode('description', 'multiple spaces here')]), + ]; + + yield 'unmatched right parenthesis in word' => [ + 'test)word', + new NodeGroup([new StringNode('test)word')]), + ]; + + yield 'unmatched right parenthesis in field' => [ + 'description:test)phrase', + new NodeGroup([new FieldNode('description', 'test)phrase')]), + ]; + + yield 'subquery followed by word' => [ + '(amount:100 category:food) shopping', + new NodeGroup([ + new NodeGroup([ + new FieldNode('amount', '100'), + new FieldNode('category', 'food'), ]), - ], - 'word with multiple spaces' => [ - 'query' => '"multiple spaces"', - 'expected' => new NodeGroup([new StringNode('multiple spaces')]), - ], - 'field with multiple spaces in value' => [ - 'query' => 'description:"multiple spaces here"', - 'expected' => new NodeGroup([new FieldNode('description', 'multiple spaces here')]), - ], - 'unmatched right parenthesis in word' => [ - 'query' => 'test)word', - 'expected' => new NodeGroup([new StringNode('test)word')]), - ], - 'unmatched right parenthesis in field' => [ - 'query' => 'description:test)phrase', - 'expected' => new NodeGroup([new FieldNode('description', 'test)phrase')]), - ], - 'subquery followed by word' => [ - 'query' => '(amount:100 category:food) shopping', - 'expected' => new NodeGroup([ - new NodeGroup([ - new FieldNode('amount', '100'), - new FieldNode('category', 'food'), - ]), - new StringNode('shopping'), - ]), - ], + new StringNode('shopping'), + ]), ]; } }