Skip to content

Commit

Permalink
integration tests and custom prefixes
Browse files Browse the repository at this point in the history
  • Loading branch information
taylorotwell committed Dec 16, 2022
1 parent 5a1eb8b commit 1ff0379
Show file tree
Hide file tree
Showing 8 changed files with 90 additions and 12 deletions.
13 changes: 10 additions & 3 deletions src/Illuminate/View/Compilers/BladeCompiler.php
Original file line number Diff line number Diff line change
Expand Up @@ -693,15 +693,22 @@ public function getClassComponentAliases()
* Register a new anonymous component path.
*
* @param string $path
* @param string|null $prefix
* @return void
*/
public function anonymousComponentPath(string $path)
public function anonymousComponentPath(string $path, string $prefix = null)
{
$this->anonymousComponentPaths[] = $path;
$prefixHash = md5($prefix ?: $path);

$this->anonymousComponentPaths[] = [
'path' => $path,
'prefix' => $prefix,
'prefixHash' => $prefixHash,
];

Container::getInstance()
->make(ViewFactory::class)
->addNamespace(md5($path), $path);
->addNamespace($prefixHash, $path);
}

/**
Expand Down
17 changes: 12 additions & 5 deletions src/Illuminate/View/Compilers/ComponentTagCompiler.php
Original file line number Diff line number Diff line change
Expand Up @@ -314,15 +314,22 @@ public function componentClass(string $component)
*/
protected function guessAnonymousComponentUsingPaths(Factory $viewFactory, string $component)
{
if (str_contains($component, ViewFinderInterface::HINT_PATH_DELIMITER)) {
return;
}
$delimiter = ViewFinderInterface::HINT_PATH_DELIMITER;

foreach ($this->blade->getAnonymousComponentPaths() as $path) {
try {
if (str_contains($component, $delimiter) &&
! str_starts_with($component, $path['prefix'].$delimiter)) {
continue;
}

$formattedComponent = str_starts_with($component, $path['prefix'].$delimiter)
? Str::after($component, $delimiter)
: $component;

if (! is_null($guess = match (true) {
$viewFactory->exists($guess = md5($path).ViewFinderInterface::HINT_PATH_DELIMITER.$component) => $guess,
$viewFactory->exists($guess = md5($path).ViewFinderInterface::HINT_PATH_DELIMITER.$component.'.index') => $guess,
$viewFactory->exists($guess = $path['prefixHash'].$delimiter.$formattedComponent) => $guess,
$viewFactory->exists($guess = $path['prefixHash'].$delimiter.$formattedComponent.'.index') => $guess,
default => null,
})) {
return $guess;
Expand Down
48 changes: 48 additions & 0 deletions tests/Integration/View/BladeAnonymousComponentTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
<?php

namespace Illuminate\Tests\Integration\View;

use Illuminate\Support\Facades\Blade;
use Illuminate\Support\Facades\View;
use InvalidArgumentException;
use Orchestra\Testbench\TestCase;

class BladeAnonymousComponentTest extends TestCase
{
public function test_anonymous_components_with_custom_paths_can_be_rendered()
{
Blade::anonymousComponentPath(__DIR__.'/anonymous-components-1', 'layouts');
Blade::anonymousComponentPath(__DIR__.'/anonymous-components-2');

$view = View::make('page')->render();

$this->assertTrue(str_contains($view, 'Panel content.'));
$this->assertTrue(str_contains($view, 'class="app-layout"'));
$this->assertTrue(str_contains($view, 'class="danger-button"'));
}

public function test_anonymous_components_with_custom_paths_cant_be_rendered_as_normal_views()
{
$this->expectException(InvalidArgumentException::class);

Blade::anonymousComponentPath(__DIR__.'/anonymous-components-1', 'layouts');
Blade::anonymousComponentPath(__DIR__.'/anonymous-components-2');

$view = View::make('layouts::app')->render();
}

public function test_anonymous_components_with_custom_paths_cant_be_rendered_as_normal_views_even_with_no_prefix()
{
$this->expectException(InvalidArgumentException::class);

Blade::anonymousComponentPath(__DIR__.'/anonymous-components-1', 'layouts');
Blade::anonymousComponentPath(__DIR__.'/anonymous-components-2');

$view = View::make('panel')->render();
}

protected function getEnvironmentSetUp($app)
{
$app['config']->set('view.paths', [__DIR__.'/anonymous-components-templates']);
}
}
3 changes: 3 additions & 0 deletions tests/Integration/View/anonymous-components-1/app.blade.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
<div class="app-layout">
{{ $slot }}
</div>
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
<div class="danger-button">
Danger button.
</div>
3 changes: 3 additions & 0 deletions tests/Integration/View/anonymous-components-2/panel.blade.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
<div class="panel">
{{ $slot }}
</div>
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
<x-layouts::app>
<x-panel>
Panel content.

<x-buttons.danger />
</x-panel>
</x-layouts::app>
8 changes: 4 additions & 4 deletions tests/View/Blade/BladeComponentTagCompilerTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -585,14 +585,14 @@ public function testClasslessComponentsWithAnonymousComponentPath()
$blade = m::mock(BladeCompiler::class)->makePartial();

$blade->shouldReceive('getAnonymousComponentPaths')->once()->andReturn([
'test-directory',
['path' => 'test-directory', 'prefix' => null, 'prefixHash' => md5('test-directory')],
]);

$compiler = $this->compiler([], [], $blade);

$result = $compiler->compileTags('<x-panel />');

$this->assertSame("##BEGIN-COMPONENT-CLASS##@component('Illuminate\View\AnonymousComponent', 'panel', ['view' => '8ee975052836fdc7da2267cf8a580b80::panel.index','data' => []])
$this->assertSame("##BEGIN-COMPONENT-CLASS##@component('Illuminate\View\AnonymousComponent', 'panel', ['view' => '".md5('test-directory')."::panel.index','data' => []])
<?php if (isset(\$attributes) && \$attributes instanceof Illuminate\View\ComponentAttributeBag && \$constructor = (new ReflectionClass(Illuminate\View\AnonymousComponent::class))->getConstructor()): ?>
<?php \$attributes = \$attributes->except(collect(\$constructor->getParameters())->map->getName()->all()); ?>
<?php endif; ?>
Expand All @@ -618,14 +618,14 @@ public function testClasslessIndexComponentsWithAnonymousComponentPath()
$blade = m::mock(BladeCompiler::class)->makePartial();

$blade->shouldReceive('getAnonymousComponentPaths')->once()->andReturn([
'test-directory',
['path' => 'test-directory', 'prefix' => null, 'prefixHash' => md5('test-directory')],
]);

$compiler = $this->compiler([], [], $blade);

$result = $compiler->compileTags('<x-panel />');

$this->assertSame("##BEGIN-COMPONENT-CLASS##@component('Illuminate\View\AnonymousComponent', 'panel', ['view' => '8ee975052836fdc7da2267cf8a580b80::panel','data' => []])
$this->assertSame("##BEGIN-COMPONENT-CLASS##@component('Illuminate\View\AnonymousComponent', 'panel', ['view' => '".md5('test-directory')."::panel','data' => []])
<?php if (isset(\$attributes) && \$attributes instanceof Illuminate\View\ComponentAttributeBag && \$constructor = (new ReflectionClass(Illuminate\View\AnonymousComponent::class))->getConstructor()): ?>
<?php \$attributes = \$attributes->except(collect(\$constructor->getParameters())->map->getName()->all()); ?>
<?php endif; ?>
Expand Down

0 comments on commit 1ff0379

Please sign in to comment.