Skip to content

Commit

Permalink
Merge pull request #26 from stevebauman/main
Browse files Browse the repository at this point in the history
Add ability for other resources to be turbo-streamable
  • Loading branch information
tonysm authored Jun 23, 2021
2 parents 1ee49ac + b25d556 commit 03032b2
Show file tree
Hide file tree
Showing 9 changed files with 131 additions and 11 deletions.
3 changes: 1 addition & 2 deletions src/Models/Naming/Name.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@

namespace Tonysm\TurboLaravel\Models\Naming;

use Illuminate\Database\Eloquent\Model;
use Illuminate\Support\Str;

class Name
Expand Down Expand Up @@ -51,7 +50,7 @@ class Name
*/
public string $element;

public static function forModel(Model $model)
public static function forModel(object $model)
{
return static::build(get_class($model));
}
Expand Down
27 changes: 24 additions & 3 deletions src/Views/RecordIdentifier.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,17 +10,22 @@ class RecordIdentifier
const NEW_PREFIX = "create";
const DELIMITER = "_";

/** @var Model */
/** @var Model|TurboStreamable */
private $record;

public function __construct(Model $record)
public function __construct(object $record)
{
throw_if(
! $this->isStreamable($record),
sprintf('[%s] must be an instance of Eloquent or TurboStreamable.', get_class($record))
);

$this->record = $record;
}

public function domId(?string $prefix = null): string
{
if ($recordId = $this->record->getKey()) {
if ($recordId = $this->streamableKey()) {
return sprintf('%s%s%s', $this->domClass($prefix), self::DELIMITER, $recordId);
}

Expand All @@ -34,4 +39,20 @@ public function domClass(?string $prefix = null): string

return trim("{$prefix}{$delimiter}{$singular}", $delimiter);
}

protected function streamableKey(): ?string
{
if ($this->record instanceof Model) {
return $this->record->getKey();
}

if ($this->record instanceof TurboStreamable) {
return $this->record->getDomId();
}
}

protected function isStreamable($record): bool
{
return $record instanceof Model || $record instanceof TurboStreamable;
}
}
8 changes: 8 additions & 0 deletions src/Views/TurboStreamable.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
<?php

namespace Tonysm\TurboLaravel\Views;

interface TurboStreamable
{
public function getDomId();
}
9 changes: 4 additions & 5 deletions src/helpers.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,30 +2,29 @@

namespace Tonysm\TurboLaravel;

use Illuminate\Database\Eloquent\Model;
use Tonysm\TurboLaravel\Views\RecordIdentifier;

/**
* Generates the DOM ID for a specific model.
*
* @param Model $model
* @param object $model
* @param string $prefix
*
* @return string
*/
function dom_id(Model $model, string $prefix = ""): string
function dom_id(object $model, string $prefix = ""): string
{
return (new RecordIdentifier($model))->domId($prefix);
}

/**
* Generates the DOM CSS Class for a specific model.
*
* @param Model $model
* @param object $model
* @param string $prefix
* @return string
*/
function dom_class(Model $model, string $prefix = ""): string
function dom_class(object $model, string $prefix = ""): string
{
return (new RecordIdentifier($model))->domClass($prefix);
}
13 changes: 13 additions & 0 deletions tests/Stubs/Models/TestTurboStreamable.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<?php

namespace Tonysm\TurboLaravel\Tests\Stubs\Models;

use Tonysm\TurboLaravel\Views\TurboStreamable;

class TestTurboStreamable implements TurboStreamable
{
public function getDomId()
{
return 'turbo-dom-id';
}
}
13 changes: 13 additions & 0 deletions tests/TestTurboStreamable.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<?php

namespace Tonysm\TurboLaravel\Tests;

use Tonysm\TurboLaravel\Views\TurboStreamable;

class TestTurboStreamable implements TurboStreamable
{
public function getDomId()
{
return 'turbo-dom-id';
}
}
44 changes: 44 additions & 0 deletions tests/Views/RecordIdentifierStreamableTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
<?php

namespace Tonysm\TurboLaravel\Tests\Views;

use RuntimeException;
use stdClass;
use Tonysm\TurboLaravel\Tests\TestCase;
use Tonysm\TurboLaravel\Tests\TestTurboStreamable;
use Tonysm\TurboLaravel\Views\RecordIdentifier;

class RecordIdentifierStreamableTest extends TestCase
{
private $streamable;
private $singular;

protected function setUp(): void
{
parent::setUp();

$this->streamable = new TestTurboStreamable;
$this->singular = "test_turbo_streamable";
}

/** @test */
public function dom_id_of_streamable()
{
$this->assertEquals("{$this->singular}_turbo-dom-id", (new RecordIdentifier($this->streamable))->domId());
}

/** @test */
public function dom_id_of_streamable_with_custom_prefix()
{
$this->assertEquals("custom_prefix_{$this->singular}_turbo-dom-id", (new RecordIdentifier($this->streamable))->domId("custom_prefix"));
}

/** @test */
public function exception_is_thrown_when_given_non_streamable_instance()
{
$this->expectException(RuntimeException::class);
$this->expectExceptionMessage('[stdClass] must be an instance of Eloquent or TurboStreamable.');

new RecordIdentifier(new stdClass);
}
}
1 change: 0 additions & 1 deletion tests/Views/RecordIdentifierTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@ protected function setUp(): void

$this->model = new TestModel(['name' => 'Hello']);
$this->singular = "test_model";
$this->plural = "test_models";
}

/** @test */
Expand Down
24 changes: 24 additions & 0 deletions tests/Views/ViewHelpersTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,18 @@ public function renders_dom_id()
$this->assertEquals('<div id="create_test_model"></div>', trim($rendersDomIdOfNewModel));
}

/** @test */
public function renders_streamable_dom_id()
{
$testStreamable = new Models\TestTurboStreamable;

$renderedDomId = View::file(__DIR__ . '/../Stubs/views/domid.blade.php', ['model' => $testStreamable])->render();
$renderedDomIdWithPrefix = View::file(__DIR__ . '/../Stubs/views/domid_with_prefix.blade.php', ['model' => $testStreamable])->render();

$this->assertEquals('<div id="test_turbo_streamable_turbo-dom-id"></div>', trim($renderedDomId));
$this->assertEquals('<div id="favorites_test_turbo_streamable_turbo-dom-id"></div>', trim($renderedDomIdWithPrefix));
}

/** @test */
public function renders_dom_class()
{
Expand All @@ -65,6 +77,18 @@ public function renders_dom_class()
$this->assertEquals('<div class="test_model"></div>', trim($rendersDomClassOfNewModel));
}

/** @test */
public function renders_streamable_dom_class()
{
$testModel = new Models\TestTurboStreamable;

$renderedDomClass = View::file(__DIR__ . '/../Stubs/views/domclass.blade.php', ['model' => $testModel])->render();
$renderedDomClassWithPrefix = View::file(__DIR__ . '/../Stubs/views/domclass_with_prefix.blade.php', ['model' => $testModel])->render();

$this->assertEquals('<div class="test_turbo_streamable"></div>', trim($renderedDomClass));
$this->assertEquals('<div class="favorites_test_turbo_streamable"></div>', trim($renderedDomClassWithPrefix));
}

/** @test */
public function can_use_helper_function()
{
Expand Down

0 comments on commit 03032b2

Please sign in to comment.