From 5e080038bcc1d591bb628a28fc9e8afb07b625bf Mon Sep 17 00:00:00 2001 From: Kyle Milloy Date: Fri, 3 May 2024 20:52:36 -0600 Subject: [PATCH] feat: allow callbacks to return additional types --- src/NowCal/NowCal.php | 44 +++++++++++++++++++++++++++---------- tests/NowCal/NowCalTest.php | 44 ++++++++++++++++++++++++++----------- 2 files changed, 63 insertions(+), 25 deletions(-) diff --git a/src/NowCal/NowCal.php b/src/NowCal/NowCal.php index 88baa23..bbe0811 100644 --- a/src/NowCal/NowCal.php +++ b/src/NowCal/NowCal.php @@ -224,9 +224,13 @@ public function uid(string|Closure $uid): self /** * Set the event's start date. */ - public function start(string|Closure|DateTime $datetime): self + public function start(string|Closure|DateTime $start): self { - $this->set('start', $datetime); + if ($start instanceof DateTime) { + $start = $start->format(static::DATETIME_FORMAT); + } + + $this->set('start', $start); return $this; } @@ -234,10 +238,14 @@ public function start(string|Closure|DateTime $datetime): self /** * Set the event's end date. */ - public function end(string|Closure|DateTime $datetime): self + public function end(string|Closure|DateTime $end): self { + if ($end instanceof DateTime) { + $end = $end->format(static::DATETIME_FORMAT); + } + if (!$this->has('duration')) { - $this->set('end', $datetime); + $this->set('end', $end); } return $this; @@ -266,8 +274,12 @@ public function location(string|Closure $location): self /** * Set the event's duration using a DateInterval. */ - public function duration(string|Closure $duration): self + public function duration(string|DateInterval|Closure $duration): self { + if ($duration instanceof DateInterval) { + $duration = $this->transformDateIntervalToString($duration); + } + if (!$this->has('end')) { $this->set('duration', $duration); } @@ -280,6 +292,10 @@ public function duration(string|Closure $duration): self */ public function timezone(string|DateTimeZone|Closure $timezone): self { + if ($timezone instanceof DateTimeZone) { + $timezone = $timezone->getName(); + } + $this->set('timezone', $timezone); return $this; @@ -323,10 +339,16 @@ protected function set(string|array $key, $val = null): void return; } - if ($this->allowed($key)) { - $this->{$key} = is_callable($val) ? $val() : $val; + if (!$this->allowed($key)) { + return; + } + + if (is_callable($val)) { + $this->set($key, $val()); return; } + + $this->{$key} = $val; } /** @@ -584,9 +606,8 @@ protected function getUidAttribute(): string return $this->uid; } - // Generate 16 bytes (128 bits) of random data or use the data passed into the function. - $data = $data ?? random_bytes(16); - assert(strlen($data) == 16); + $data = random_bytes(16); + assert(strlen($data) === 16); // Set version to 0100 $data[6] = chr(ord($data[6]) & 0x0f | 0x40); @@ -668,8 +689,7 @@ protected function convertStringToPascalCase(string $string): string */ protected function createDateTime(string|DateTime|Closure $datetime = 'now'): string { - return (new DateTime($datetime ?? 'now')) - ->format(static::DATETIME_FORMAT); + return (new DateTime($datetime))->format(static::DATETIME_FORMAT); } /** diff --git a/tests/NowCal/NowCalTest.php b/tests/NowCal/NowCalTest.php index 0b9adb7..4b040e6 100644 --- a/tests/NowCal/NowCalTest.php +++ b/tests/NowCal/NowCalTest.php @@ -2,7 +2,10 @@ namespace Tests\NowCal; +use DateInterval; use DateTime; +use DateTimeZone; +use NowCal\NowCal; use Tests\TestCase; class NowCalTest extends TestCase @@ -31,8 +34,10 @@ public function test_it_can_export_a_path_to_a_file() public function test_it_can_get_set_a_duration() { $this->nowcal->duration($time = '1h'); - $this->assertEquals($time, $this->nowcal->duration); + + $this->nowcal->duration($time = new DateInterval('PT1H')); + $this->assertEquals('PT1H', $this->nowcal->duration); } public function test_it_casts_end_as_an_iso_duration() @@ -62,12 +67,11 @@ public function test_it_cannot_have_both_an_end_and_duration() public function test_it_casts_end_as_a_datetime() { $this->nowcal->end($time = 'October 5, 2019 6:03PM'); - $format = 'Ymd\THis\Z'; - $this->assertStringContainsString((new DateTime($time))->format($format), $this->nowcal->plain); + $this->assertStringContainsString((new DateTime($time))->format(NowCal::DATETIME_FORMAT), $this->nowcal->plain); } - public function test_it_can_get_and_set_a_end_time() + public function test_it_can_get_and_set_a_location() { $this->nowcal->location($location = '123 Fake Street NW'); @@ -84,16 +88,32 @@ public function test_it_includes_location_in_its_output() public function test_it_can_get_and_set_a_start_time() { $this->nowcal->start($time = 'now'); + $this->assertEquals($time, $this->nowcal->start); + $this->nowcal->start(fn() => $time = 'now'); $this->assertEquals($time, $this->nowcal->start); + + $this->nowcal->start($time = new DateTime('now')); + $this->assertEquals($time->format(NowCal::DATETIME_FORMAT), $this->nowcal->start); + } + + public function test_it_can_get_and_set_an_end_time() + { + $this->nowcal->end($time = 'now'); + $this->assertEquals($time, $this->nowcal->end); + + $this->nowcal->end(fn() => $time = 'now'); + $this->assertEquals($time, $this->nowcal->end); + + $this->nowcal->end($time = new DateTime('now')); + $this->assertEquals($time->format(NowCal::DATETIME_FORMAT), $this->nowcal->end); } public function test_it_casts_start_as_a_datetime() { - $format = 'Ymd\THis\Z'; $this->nowcal->start($time = 'October 5, 2019 6:03PM'); - $this->assertStringContainsString((new DateTime($time))->format($format), $this->nowcal->plain); + $this->assertStringContainsString((new DateTime($time))->format(NowCal::DATETIME_FORMAT), $this->nowcal->plain); } public function test_it_can_get_and_set_a_summary() @@ -112,15 +132,15 @@ public function test_it_includes_the_summary_in_its_output() public function test_it_can_set_a_timezone() { - $this->nowcal->timezone($timezone = 'America/Edmonton') - ->start('now'); - + $this->nowcal->timezone($timezone = 'America/Edmonton')->start('now'); $this->assertStringContainsString($timezone, $this->nowcal->plain); + + $this->nowcal->timezone($timezone = new DateTimeZone('America/Edmonton'))->start('now'); + $this->assertStringContainsString($timezone->getName(), $this->nowcal->plain); + $this->assertStringContainsString('BEGIN:VTIMEZONE', $this->nowcal->plain); $this->assertStringContainsString('BEGIN:DAYLIGHT', $this->nowcal->plain); $this->assertStringContainsString('BEGIN:STANDARD', $this->nowcal->plain); - - echo $this->nowcal->plain; } public function test_places_that_do_not_witness_dst_dont_get_daylight_hours() @@ -131,8 +151,6 @@ public function test_places_that_do_not_witness_dst_dont_get_daylight_hours() $this->assertStringContainsString($timezone, $this->nowcal->plain); $this->assertStringContainsString('BEGIN:VTIMEZONE', $this->nowcal->plain); $this->assertStringNotContainsString('BEGIN:DAYLIGHT', $this->nowcal->plain); - - echo $this->nowcal->plain; } public function test_it_can_customize_the_uid()