123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272 |
- <?php
- declare(strict_types=1);
- /**
- * This file is part of the Carbon package.
- *
- * (c) Brian Nesbitt <brian@nesbot.com>
- *
- * For the full copyright and license information, please view the LICENSE
- * file that was distributed with this source code.
- */
- namespace Tests\CarbonPeriod;
- use BadMethodCallException;
- use Carbon\Carbon;
- use Carbon\CarbonPeriod;
- use Carbon\CarbonPeriodImmutable;
- use ReflectionClass;
- use Tests\AbstractTestCase;
- use Tests\CarbonPeriod\Fixtures\MacroableClass;
- use Tests\CarbonPeriod\Fixtures\Mixin;
- use Tests\CarbonPeriod\Fixtures\MixinTrait;
- class MacroTest extends AbstractTestCase
- {
- private function setStaticProperty(string $class, string $property, $value): void
- {
- $reflection = new ReflectionClass($class);
- if (PHP_VERSION >= 7.4) {
- $reflection->setStaticPropertyValue($property, $value);
- return;
- }
- $property = $reflection->getProperty($property);
- $property->setAccessible(true);
- $property->setValue($value);
- }
- protected function tearDown(): void
- {
- $this->setStaticProperty($this->periodClass, 'macros', []);
- parent::tearDown();
- }
- public function testCallMacro()
- {
- $periodClass = $this->periodClass;
- $periodClass::macro('onlyWeekdays', function () {
- /** @var CarbonPeriod $period */
- $period = $this;
- return $period->addFilter(function ($date) {
- return !\in_array($date->dayOfWeek, [Carbon::SATURDAY, Carbon::SUNDAY], true);
- });
- });
- /** @var mixed $period */
- $period = $periodClass::create('2018-05-10', '2018-05-14');
- $result = $period->onlyWeekdays();
- $this->assertSame(
- $periodClass === CarbonPeriod::class,
- $period === $result,
- 'Must be same object if mutable'
- );
- $this->assertSame(
- $this->standardizeDates(['2018-05-10', '2018-05-11', '2018-05-14']),
- $this->standardizeDates($result)
- );
- }
- public function testParameterOtherThanSelfIsNotGivenPeriodInstance()
- {
- $periodClass = $this->periodClass;
- $periodClass::macro('foobar', function ($param = 123) {
- return $param;
- });
- /** @var mixed $period */
- $period = $periodClass::create();
- $this->assertSame(123, $period->foobar());
- }
- public function testPassPeriodInstanceAfterOptionalParameters()
- {
- $periodClass = $this->periodClass;
- $periodClass::macro('formatStartDate', function ($format = 'l, j F Y') {
- /** @var CarbonPeriod $period */
- $period = $this;
- return $period->getStartDate()->format($format);
- });
- /** @var mixed $period */
- $period = $periodClass::start('2016-09-11');
- $this->assertSame(
- 'Sunday, 11 September 2016',
- $period->formatStartDate()
- );
- }
- public function testMacroIsBindedToDatePeriodInstance()
- {
- $periodClass = $this->periodClass;
- $periodClass::macro('myself', function () {
- return $this;
- });
- /** @var mixed $period */
- $period = new $periodClass();
- $this->assertInstanceOf($periodClass, $period->myself());
- $this->assertSame($period, $period->myself());
- }
- public function testCallMacroStatically()
- {
- $periodClass = $this->periodClass;
- $periodClass::macro('countWeekdaysBetween', function ($from, $to) use ($periodClass) {
- return $periodClass::create($from, $to)
- ->addFilter(function ($date) {
- return !\in_array($date->dayOfWeek, [Carbon::SATURDAY, Carbon::SUNDAY], true);
- })
- ->count();
- });
- $this->assertSame(
- 3,
- $periodClass::countWeekdaysBetween('2018-05-10', '2018-05-14')
- );
- }
- public function testMacroIsBoundToDatePeriodClass()
- {
- $periodClass = $this->periodClass;
- $periodClass::macro('newMyself', function () {
- return new static();
- });
- $this->assertInstanceOf($periodClass, $periodClass::newMyself());
- }
- public function testRegisterNonClosureMacro()
- {
- $periodClass = $this->periodClass;
- $periodClass::macro('lower', 'strtolower');
- /** @var mixed $period */
- $period = new $periodClass();
- $this->assertSame('abc', $period->lower('ABC'));
- $this->assertSame('abc', $periodClass::lower('ABC'));
- }
- public function testRegisterMixin()
- {
- $periodClass = $this->periodClass;
- $periodClass::mixin(new Mixin());
- $this->assertNull($periodClass::getFoo());
- $periodClass::setFoo('bar');
- $this->assertSame('bar', $periodClass::getFoo());
- }
- public function testCallNonExistingMacro()
- {
- $this->expectExceptionObject(new BadMethodCallException(
- 'Method nonExistingMacro does not exist.'
- ));
- $periodClass = $this->periodClass;
- /** @var mixed $period */
- $period = $periodClass::create();
- $period->nonExistingMacro();
- }
- public function testCallNonExistingMacroStatically()
- {
- $this->expectExceptionObject(new BadMethodCallException(
- 'Method nonExistingMacro does not exist.'
- ));
- $periodClass = $this->periodClass;
- $periodClass::nonExistingMacro();
- }
- public function testOverrideAlias()
- {
- $periodClass = $this->periodClass;
- $periodClass::macro('recurrences', function () {
- return 'foo';
- });
- $this->assertSame('foo', $periodClass::recurrences());
- }
- public function testInstatiateViaStaticMacroCall()
- {
- $periodClass = $this->periodClass;
- $periodClass::macro('fromTomorrow', function () {
- /** @var CarbonPeriod $period */
- $period = $this;
- return $period->setStartDate(Carbon::tomorrow());
- });
- $period = $periodClass::fromTomorrow();
- $this->assertEquals(Carbon::tomorrow(), $period->getStartDate());
- }
- public function testMixinInstance()
- {
- require_once __DIR__.'/Fixtures/MixinTrait.php';
- require_once __DIR__.'/Fixtures/MacroableClass.php';
- $periodClass = $this->periodClass;
- $periodClass::mixin(MixinTrait::class);
- $period = $periodClass::create('2023-06-10', '2023-06-12');
- $copy = $period->copyOneMoreDay();
- $this->assertSame('Every 1 day from 2023-06-10 to 2023-06-12', (string) $period);
- $this->assertSame('Every 1 day from 2023-06-10 to 2023-06-13', (string) $copy);
- $mutated = $period->oneMoreDay();
- $immutable = ($this->periodClass === CarbonPeriodImmutable::class);
- $expectedEnd = $immutable ? '2023-06-12' : '2023-06-13';
- $this->assertSame('Every 1 day from 2023-06-10 to 2023-06-13', (string) $mutated);
- $this->assertSame("Every 1 day from 2023-06-10 to $expectedEnd", (string) $period);
- $expectedResult = $immutable ? 'a new instance' : 'the same instance';
- $this->assertSame(
- $immutable,
- ($mutated !== $period),
- "{$this->periodClass}::oneMoreDay() should return $expectedResult"
- );
- $this->assertNotSame($copy, $period);
- $this->assertSame('2023-06-14', $mutated->endNextDay()->format('Y-m-d'));
- $this->assertSame($this->periodClass === CarbonPeriodImmutable::class
- ? '2023-06-13'
- : '2023-06-14', $period->endNextDay()->format('Y-m-d'));
- MacroableClass::mixin(MixinTrait::class);
- $obj = new MacroableClass();
- $result = $obj
- ->setEndDate(Carbon::parse('2023-06-01'))
- ->oneMoreDay();
- $endDate = $result->getEndDate();
- $this->assertInstanceOf(MacroableClass::class, $result);
- $this->assertNotSame(MacroableClass::class, \get_class($result));
- $this->assertSame(Carbon::class, \get_class($endDate));
- $this->assertSame('2023-06-02', $endDate->format('Y-m-d'));
- }
- }
|