<?php
use App\Prompts\LiveSuggestPrompt;
use App\Prompts\Renderers\LiveSuggestPromptRenderer;
use Illuminate\Process\PendingProcess;
use Illuminate\Support\Facades\Process;
use Laravel\Prompts\Key;
it('searches intent tags using the list command logic and passes through the limit', function () {
Process::fake(function (PendingProcess $process) {
return match ($process->command) {
['pijul', 'log', '--output-format', 'json', '--limit', '50'] => Process::result(json_encode([
['message' => 'feat(pijul-qol): first'],
['message' => 'feat(pijul-qol:move-to-zero): second'],
['message' => 'fix(cli): third'],
], JSON_THROW_ON_ERROR)),
default => Process::result('', 'Unexpected command.', 1),
};
});
$this->artisan('pijul:search-intent-tags', [
'query' => 'zero',
'--limit' => '50',
])
->expectsOutput('feat(pijul-qol:move-to-zero)')
->assertExitCode(0);
Process::assertRanTimes(fn (PendingProcess $process) => $process->command === [
'pijul',
'log',
'--output-format',
'json',
'--limit',
'50',
], 1);
});
it('can search for an exact tag match', function () {
Process::fake(function (PendingProcess $process) {
return match ($process->command) {
['pijul', 'log', '--output-format', 'json'] => Process::result(json_encode([
['message' => 'feat(pijul-qol): first'],
['message' => 'feat(pijul-qol:move-to-zero): second'],
], JSON_THROW_ON_ERROR)),
default => Process::result('', 'Unexpected command.', 1),
};
});
$this->artisan('pijul:search-intent-tags', [
'query' => 'feat(pijul-qol)',
'--exact' => true,
])
->expectsOutput('feat(pijul-qol)')
->assertExitCode(0);
});
it('shows live suggestions starting from all tags when prompted for a query', function () {
Process::fake(function (PendingProcess $process) {
return match ($process->command) {
['pijul', 'log', '--output-format', 'json'] => Process::result(json_encode([
['message' => 'feat(pijul-qol): first'],
['message' => 'feat(pijul-qol:move-to-zero): second'],
['message' => 'fix(cli): third'],
], JSON_THROW_ON_ERROR)),
default => Process::result('', 'Unexpected command.', 1),
};
});
LiveSuggestPrompt::fake(['z', 'e', 'r', 'o', Key::ENTER]);
$this->artisan('pijul:search-intent-tags')
->expectsOutput('feat(pijul-qol:move-to-zero)')
->assertExitCode(0);
});
it('renders initial live suggestions before any query is typed', function () {
LiveSuggestPrompt::fake();
$prompt = new LiveSuggestPrompt(
label: 'Search query',
options: fn (string $value): array => $value === ''
? ['feat(pijul-qol)', 'feat(pijul-qol:move-to-zero)', 'fix(cli)']
: ['fix(cli)'],
placeholder: 'Type to filter intent tags...',
scroll: 10,
required: 'Please provide a search query.',
);
$output = (new LiveSuggestPromptRenderer($prompt))($prompt);
expect(preg_replace("/\e\[[0-9;?]*[A-Za-z]/", '', $output))
->toContain('feat(pijul-qol)')
->toContain('fix(cli)');
});
it('returns all tags when the live filter has no input yet', function () {
$command = app(App\Commands\PijulSearchIntentTagsCommand::class);
$method = new ReflectionMethod($command, 'suggestedTags');
$method->setAccessible(true);
expect($method->invoke($command, [
'feat(pijul-qol)',
'feat(pijul-qol:move-to-zero)',
'fix(cli)',
], ''))->toBe([
'feat(pijul-qol)',
'feat(pijul-qol:move-to-zero)',
'fix(cli)',
]);
});