Skip to content

Commit

Permalink
Add support for array values
Browse files Browse the repository at this point in the history
  • Loading branch information
brendt committed May 29, 2024
1 parent 363f11b commit c6d8252
Show file tree
Hide file tree
Showing 6 changed files with 190 additions and 6 deletions.
123 changes: 123 additions & 0 deletions src/HasConsole.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,123 @@
<?php

declare(strict_types=1);

namespace Tempest\Console;

use Closure;

trait HasConsole
{
public function __construct(private readonly Console $console)
{
}

public function readln(): string
{
return $this->console->readln();
}

public function read(int $bytes): string
{
return $this->console->read($bytes);
}

public function write(string $contents): self
{
$this->console->write($contents);

return $this;
}

public function writeln(string $line = ''): self
{
$this->console->writeln($line);

return $this;
}

/**
* @param string $question
* @param array|null $options
* @param mixed|null $default
* @param bool $multiple
* @param bool $asList
* @param \Tempest\Validation\Rule[] $validation
* @return string|array
*/
public function ask(
string $question,
?array $options = null,
mixed $default = null,
bool $multiple = false,
bool $asList = false,
array $validation = [],
): string|array {
return $this->console->ask(
question: $question,
options: $options,
default: $default,
multiple: $multiple,
asList: $asList,
validation: $validation,
);
}

public function confirm(string $question, bool $default = false): bool
{
return $this->console->confirm(
question: $question,
default: $default,
);
}

public function password(string $label = 'Password', bool $confirm = false): string
{
return $this->console->password(
label: $label,
confirm: $confirm,
);
}

public function progressBar(iterable $data, Closure $handler): array
{
return $this->console->progressBar(
data: $data,
handler: $handler,
);
}

/**
* @param string $label
* @param Closure(string $search): array $search
* @return mixed
*/
public function search(string $label, Closure $search): mixed
{
return $this->console->search(
label: $label,
search: $search,
);
}

public function info(string $line): self
{
$this->console->info($line);

return $this;
}

public function error(string $line): self
{
$this->console->error($line);

return $this;
}

public function success(string $line): self
{
$this->console->success($line);

return $this;
}
}
8 changes: 4 additions & 4 deletions src/Input/ConsoleArgumentBag.php
Original file line number Diff line number Diff line change
Expand Up @@ -34,16 +34,14 @@ public function __construct(array $arguments)

$this->path = [$cli, $commandName];

foreach (array_values($arguments) as $position => $argument) {
foreach ($arguments as $argument) {
if (str_starts_with($argument, '-') && ! str_starts_with($argument, '--')) {
$flags = str_split($argument);
unset($flags[0]);

foreach ($flags as $flag) {
$arguments[] = "-{$flag}";
}

unset($arguments[$position]);
}
}

Expand Down Expand Up @@ -107,7 +105,9 @@ public function findFor(ConsoleArgumentDefinition $argumentDefinition): ?Console

public function add(ConsoleInputArgument $argument): self
{
$this->arguments[] = $argument;
$key = $argument->name ?? $argument->position;

$this->arguments[$key] = $argument->merge($this->arguments[$key] ?? null);

return $this;
}
Expand Down
15 changes: 15 additions & 0 deletions src/Input/ConsoleInputArgument.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@

namespace Tempest\Console\Input;

use Tempest\Support\ArrayHelper;

final class ConsoleInputArgument
{
public function __construct(
Expand Down Expand Up @@ -70,4 +72,17 @@ private static function parseNamedArgument(string $argument): array

return [$key, $value];
}

public function merge(?ConsoleInputArgument $other): self
{
$clone = clone $this;

if ($other === null) {
return $clone;
}

$clone->value = array_values([...ArrayHelper::wrap($other->value), ...ArrayHelper::wrap($this->value)]);

return $clone;
}
}
5 changes: 5 additions & 0 deletions src/Testing/ConsoleTester.php
Original file line number Diff line number Diff line change
Expand Up @@ -147,6 +147,11 @@ public function useInteractiveTerminal(): self
return $this;
}

public function assertSee(string $text): self
{
return $this->assertContains($text);
}

public function assertContains(string $text): self
{
Assert::assertStringContainsString(
Expand Down
26 changes: 24 additions & 2 deletions tests/ConsoleArgumentBagTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -31,12 +31,12 @@ public function test_argument_bag_works(): void
$this->assertSame(0, $firstArg->position);
$this->assertNull($firstArg->name);

$forceFlag = $bag->all()[1];
$forceFlag = $bag->all()['force'];
$this->assertSame(true, $forceFlag->value);
$this->assertSame(null, $forceFlag->position);
$this->assertSame('force', $forceFlag->name);

$timesFlag = $bag->all()[2];
$timesFlag = $bag->all()['times'];
$this->assertSame('2', $timesFlag->value);
$this->assertSame(null, $timesFlag->position);
$this->assertSame('times', $timesFlag->name);
Expand Down Expand Up @@ -69,4 +69,26 @@ public function test_short_flags_are_mapped_to_parameters_directly(): void
->call('flags:short -ab')
->assertContains('ok');
}

public function test_array_input(): void
{
$argv = [
'tempest',
'test',
'--input=a',
'--input=b',
'--input=c',
];

$bag = new ConsoleArgumentBag($argv);

$this->assertSame(['a', 'b', 'c'], $bag->get('input')->value);
}

public function test_array_input_to_command(): void
{
$this->console
->call('array_input --input=a --input=b')
->assertContains('["a","b"]');
}
}
19 changes: 19 additions & 0 deletions tests/Fixtures/ArrayInputCommand.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
<?php

declare(strict_types=1);

namespace Tests\Tempest\Console\Fixtures;

use Tempest\Console\ConsoleCommand;
use Tempest\Console\HasConsole;

final readonly class ArrayInputCommand
{
use HasConsole;

#[ConsoleCommand('array_input')]
public function __invoke(array $input): void
{
$this->writeln(json_encode($input));
}
}

0 comments on commit c6d8252

Please sign in to comment.