Skip to content

Commit

Permalink
feat: allow callbacks to return additional types
Browse files Browse the repository at this point in the history
  • Loading branch information
kylemilloy committed May 4, 2024
1 parent 8f882b2 commit 5e08003
Show file tree
Hide file tree
Showing 2 changed files with 63 additions and 25 deletions.
44 changes: 32 additions & 12 deletions src/NowCal/NowCal.php
Original file line number Diff line number Diff line change
Expand Up @@ -224,20 +224,28 @@ 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;
}

/**
* 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;
Expand Down Expand Up @@ -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);
}
Expand All @@ -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;
Expand Down Expand Up @@ -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;
}

/**
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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);
}

/**
Expand Down
44 changes: 31 additions & 13 deletions tests/NowCal/NowCalTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,10 @@

namespace Tests\NowCal;

use DateInterval;
use DateTime;
use DateTimeZone;
use NowCal\NowCal;
use Tests\TestCase;

class NowCalTest extends TestCase
Expand Down Expand Up @@ -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()
Expand Down Expand Up @@ -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');

Expand All @@ -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()
Expand All @@ -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()
Expand All @@ -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()
Expand Down

0 comments on commit 5e08003

Please sign in to comment.