Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
Refactor test
Signed-off-by: Pushpak Chhajed <[email protected]>
  • Loading branch information
pushpak1300 committed Dec 15, 2025
commit f1cc9a57ecf99bf7d035e428c6ac59476394d269
9 changes: 9 additions & 0 deletions src/BoostServiceProvider.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@
use Illuminate\Support\Facades\Route;
use Illuminate\Support\ServiceProvider;
use Illuminate\View\Compilers\BladeCompiler;
use Laravel\Boost\Install\GuidelineAssist;
use Laravel\Boost\Install\GuidelineConfig;
use Laravel\Boost\Mcp\Boost;
use Laravel\Boost\Middleware\InjectBoost;
use Laravel\Mcp\Facades\Mcp;
Expand Down Expand Up @@ -58,6 +60,13 @@ public function register(): void

return $roster;
});

$this->app->singleton(GuidelineConfig::class, fn (): GuidelineConfig => new GuidelineConfig);

$this->app->singleton(GuidelineAssist::class, fn ($app): GuidelineAssist => new GuidelineAssist(
$app->make(Roster::class),
$app->make(GuidelineConfig::class)
));
}

public function boot(Router $router): void
Expand Down
4 changes: 1 addition & 3 deletions src/Mcp/Boost.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@
namespace Laravel\Boost\Mcp;

use InvalidArgumentException;
use Laravel\Boost\Install\GuidelineAssist;
use Laravel\Boost\Mcp\Methods\CallToolWithExecutor;
use Laravel\Boost\Mcp\Prompts\ThirdPartyPrompt;
use Laravel\Boost\Mcp\Resources\ThirdPartyResource;
Expand Down Expand Up @@ -148,13 +147,12 @@ private function discoverThirdPartyPrimitives(string $primitiveType): array
};

$primitives = [];
$guidelineAssist = app(GuidelineAssist::class);

foreach (Composer::packagesDirectoriesWithBoostGuidelines() as $package => $path) {
$corePath = $path.DIRECTORY_SEPARATOR.'core.blade.php';

if (file_exists($corePath)) {
$primitives[] = new $primitiveClass($guidelineAssist, $package, $corePath);
$primitives[] = new $primitiveClass($package, $corePath);
}
}

Expand Down
11 changes: 9 additions & 2 deletions src/Mcp/Prompts/Concerns/RendersBladeGuidelines.php
Original file line number Diff line number Diff line change
Expand Up @@ -62,8 +62,15 @@ protected function renderBlade(string $bladePath): string

$rendered = $this->renderContent($content, $bladePath);

return str_replace(array_keys($this->storedSnippets), array_values($this->storedSnippets), $rendered);
$rendered = str_replace(array_keys($this->storedSnippets), array_values($this->storedSnippets), $rendered);

$this->storedSnippets = [];

return $rendered;
}

abstract protected function getGuidelineAssist(): GuidelineAssist;
protected function getGuidelineAssist(): GuidelineAssist
{
return app(GuidelineAssist::class);
}
}
7 changes: 0 additions & 7 deletions src/Mcp/Prompts/ThirdPartyPrompt.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@

namespace Laravel\Boost\Mcp\Prompts;

use Laravel\Boost\Install\GuidelineAssist;
use Laravel\Boost\Mcp\Prompts\Concerns\RendersBladeGuidelines;
use Laravel\Mcp\Response;
use Laravel\Mcp\Server\Prompt;
Expand All @@ -14,7 +13,6 @@ class ThirdPartyPrompt extends Prompt
use RendersBladeGuidelines;

public function __construct(
protected GuidelineAssist $guidelineAssist,
protected string $packageName,
protected string $bladePath,
) {
Expand All @@ -30,9 +28,4 @@ public function handle(): Response

return Response::text($content);
}

protected function getGuidelineAssist(): GuidelineAssist
{
return $this->guidelineAssist;
}
}
9 changes: 2 additions & 7 deletions src/Mcp/Resources/ThirdPartyResource.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@

namespace Laravel\Boost\Mcp\Resources;

use Laravel\Boost\Install\GuidelineAssist;
use Laravel\Boost\Mcp\Prompts\Concerns\RendersBladeGuidelines;
use Laravel\Mcp\Response;
use Laravel\Mcp\Server\Resource;
Expand All @@ -14,10 +13,11 @@ class ThirdPartyResource extends Resource
use RendersBladeGuidelines;

public function __construct(
protected GuidelineAssist $guidelineAssist,
protected string $packageName,
protected string $bladePath,
) {
$this->name = $this->packageName;
$this->title = $this->packageName;
$this->uri = "file://instructions/{$packageName}.md";
$this->description = "Guidelines for {$packageName}";
$this->mimeType = 'text/markdown';
Expand All @@ -29,9 +29,4 @@ public function handle(): Response

return Response::text($content);
}

protected function getGuidelineAssist(): GuidelineAssist
{
return $this->guidelineAssist;
}
}
79 changes: 44 additions & 35 deletions tests/Feature/Mcp/Prompts/BladePromptTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,26 +2,17 @@

declare(strict_types=1);

use Laravel\Boost\Install\GuidelineAssist;
use Laravel\Boost\Install\GuidelineConfig;
use Laravel\Boost\Install\Herd;
use Laravel\Boost\Mcp\Prompts\ThirdPartyPrompt;
use Laravel\Roster\Roster;

beforeEach(function (): void {
// Create a test blade file
$this->testBladePath = sys_get_temp_dir().'/test-guideline.blade.php';
file_put_contents($this->testBladePath, '# Test Guideline

This is a test guideline for testing.
This is a test guideline for testing.

## Rules
- Follow best practices
- Write clean code');

$roster = app(Roster::class);
$herd = app(Herd::class);
$this->guidelineAssist = new GuidelineAssist($roster, new GuidelineConfig, $herd);
## Rules
- Follow best practices
- Write clean code');
});

afterEach(function (): void {
Expand All @@ -30,8 +21,8 @@
}
});

test('it renders blade file as prompt', function (): void {
$prompt = new ThirdPartyPrompt($this->guidelineAssist, 'acme/payments', $this->testBladePath);
it('renders a blade file as a prompt', function (): void {
$prompt = new ThirdPartyPrompt('acme/payments', $this->testBladePath);

$response = $prompt->handle();

Expand All @@ -42,30 +33,24 @@
->toolTextContains('Write clean code');
});

test('it generates correct prompt name from package', function (): void {
$prompt = new ThirdPartyPrompt($this->guidelineAssist, 'acme/payments', $this->testBladePath);
it('generates correct metadata from the package name', function (): void {
$prompt = new ThirdPartyPrompt('acme/payments', $this->testBladePath);

expect($prompt->name())->toBe('acme/payments');
expect($prompt->name())->toBe('acme/payments')
->and($prompt->description())->toBe('Guidelines for acme/payments');
});

test('it generates correct description from package', function (): void {
$prompt = new ThirdPartyPrompt($this->guidelineAssist, 'acme/payments', $this->testBladePath);

expect($prompt->description())->toBe('Guidelines for acme/payments');
});

test('it handles non-existent blade file gracefully', function (): void {
$prompt = new ThirdPartyPrompt($this->guidelineAssist, 'acme/test', '/non/existent/path.blade.php');
it('handles a non-existent blade file gracefully', function (): void {
$prompt = new ThirdPartyPrompt('acme/test', '/non/existent/path.blade.php');

$response = $prompt->handle();

expect($response)->isToolResult()
->toolHasNoError();
expect($response)->isToolResult()->toolHasNoError()
->and((string) $response->content())->toBe('');

expect((string) $response->content())->toBe('');
});

test('it processes backticks in blade content', function (): void {
it('processes backticks in blade content', function (): void {
$bladeContent = '# Guideline

Use `Model::factory()` to create models.
Expand All @@ -76,15 +61,15 @@

file_put_contents($this->testBladePath, $bladeContent);

$prompt = new ThirdPartyPrompt($this->guidelineAssist, 'test/package', $this->testBladePath);
$prompt = new ThirdPartyPrompt('test/package', $this->testBladePath);
$response = $prompt->handle();

expect($response)->isToolResult()
->toolTextContains('`Model::factory()`')
->toolTextContains('```php');
});

test('it processes php tags in blade content', function (): void {
it('processes php tags in blade content', function (): void {
$bladeContent = '# Guideline

Example code:
Expand All @@ -95,15 +80,15 @@

file_put_contents($this->testBladePath, $bladeContent);

$prompt = new ThirdPartyPrompt($this->guidelineAssist, 'test/package', $this->testBladePath);
$prompt = new ThirdPartyPrompt('test/package', $this->testBladePath);
$response = $prompt->handle();

expect($response)->isToolResult()
->toolTextContains('<?php')
->toolTextContains('echo "Hello World"');
});

test('it processes boost snippets', function (): void {
it('processes boost snippets', function (): void {
$bladeContent = '# Guideline

@boostsnippet(\'example\', \'php\')
Expand All @@ -114,10 +99,34 @@ function example() {

file_put_contents($this->testBladePath, $bladeContent);

$prompt = new ThirdPartyPrompt($this->guidelineAssist, 'test/package', $this->testBladePath);
$prompt = new ThirdPartyPrompt('test/package', $this->testBladePath);
$response = $prompt->handle();

expect($response)->isToolResult()
->toolTextContains('<code-snippet name="example" lang="php">')
->toolTextContains('function example()');
});

it('clears stored snippets between multiple handle calls', function (): void {
$bladeContent = '# Guideline

@boostsnippet(\'example\', \'php\')
function example() {
return true;
}
@endboostsnippet';

file_put_contents($this->testBladePath, $bladeContent);

$prompt = new ThirdPartyPrompt('test/package', $this->testBladePath);

$response1 = $prompt->handle();
$content1 = (string) $response1->content();

$response2 = $prompt->handle();
$content2 = (string) $response2->content();

expect($content1)->toBe($content2)
->and($content1)->toContain('<code-snippet name="example" lang="php">')
->and($content1)->not->toContain('___BOOST_SNIPPET_');
});
74 changes: 0 additions & 74 deletions tests/Feature/Mcp/Prompts/PromptDiscoveryTest.php

This file was deleted.

Loading