diff --git a/src/Illuminate/Support/Sleep.php b/src/Illuminate/Support/Sleep.php index 041535b9b42f..101ed3b36f50 100644 --- a/src/Illuminate/Support/Sleep.php +++ b/src/Illuminate/Support/Sleep.php @@ -5,11 +5,14 @@ use Carbon\Carbon; use Carbon\CarbonInterval; use DateInterval; +use Illuminate\Support\Traits\Macroable; use PHPUnit\Framework\Assert as PHPUnit; use RuntimeException; class Sleep { + use Macroable; + /** * The total duration to sleep. * @@ -53,19 +56,7 @@ class Sleep */ public function __construct($duration) { - if (! $duration instanceof DateInterval) { - $this->duration = CarbonInterval::microsecond(0); - - $this->pending = $duration; - } else { - $duration = CarbonInterval::instance($duration); - - if ($duration->totalMicroseconds < 0) { - $duration = CarbonInterval::seconds(0); - } - - $this->duration = $duration; - } + $this->duration($duration); } /** @@ -116,6 +107,32 @@ public static function sleep($duration) return (new static($duration))->seconds(); } + /** + * Sleep for the given duration. Replaces any previously defined duration. + * + * @param \DateInterval|int|float $duration + * @return $this + */ + protected function duration($duration) + { + if (! $duration instanceof DateInterval) { + $this->duration = CarbonInterval::microsecond(0); + + $this->pending = $duration; + } else { + $duration = CarbonInterval::instance($duration); + + if ($duration->totalMicroseconds < 0) { + $duration = CarbonInterval::seconds(0); + } + + $this->duration = $duration; + $this->pending = null; + } + + return $this; + } + /** * Sleep for the given number of minutes. * diff --git a/tests/Support/SleepTest.php b/tests/Support/SleepTest.php index 13c7ed4d9d3b..af73291014f1 100644 --- a/tests/Support/SleepTest.php +++ b/tests/Support/SleepTest.php @@ -414,4 +414,53 @@ public function testAssertSlept() $this->assertSame("The expected sleep was found [0] times instead of [1].\nFailed asserting that 0 is identical to 1.", $e->getMessage()); } } + + public function testItCanCreateMacrosViaMacroable() + { + Sleep::fake(); + + Sleep::macro('forSomeConfiguredAmountOfTime', static function () { + return Sleep::for(3)->seconds(); + }); + + Sleep::macro('useSomeOtherAmountOfTime', function () { + /** @var Sleep $this */ + return $this->duration(1.234)->seconds(); + }); + + Sleep::macro('andSomeMoreGranularControl', function () { + /** @var Sleep $this */ + return $this->and(567)->microseconds(); + }); + + // A static macro can be referenced + $sleep = Sleep::forSomeConfiguredAmountOfTime(); + $this->assertSame($sleep->duration->totalMicroseconds, 3000000); + + // A macro can specify a new duration + $sleep = $sleep->useSomeOtherAmountOfTime(); + $this->assertSame($sleep->duration->totalMicroseconds, 1234000); + + // A macro can supplement an existing duration + $sleep = $sleep->andSomeMoreGranularControl(); + $this->assertSame($sleep->duration->totalMicroseconds, 1234567); + } + + public function testItCanReplacePreviouslyDefinedDurations() + { + Sleep::fake(); + + Sleep::macro('setDuration', function ($duration) { + return $this->duration($duration); + }); + + $sleep = Sleep::for(1)->second(); + $this->assertSame($sleep->duration->totalMicroseconds, 1000000); + + $sleep->setDuration(2)->second(); + $this->assertSame($sleep->duration->totalMicroseconds, 2000000); + + $sleep->setDuration(500)->milliseconds(); + $this->assertSame($sleep->duration->totalMicroseconds, 500000); + } }