Skip to content

Commit c6d8252

Browse files
committed
Add support for array values
1 parent 363f11b commit c6d8252

File tree

6 files changed

+190
-6
lines changed

6 files changed

+190
-6
lines changed

src/HasConsole.php

Lines changed: 123 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,123 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Tempest\Console;
6+
7+
use Closure;
8+
9+
trait HasConsole
10+
{
11+
public function __construct(private readonly Console $console)
12+
{
13+
}
14+
15+
public function readln(): string
16+
{
17+
return $this->console->readln();
18+
}
19+
20+
public function read(int $bytes): string
21+
{
22+
return $this->console->read($bytes);
23+
}
24+
25+
public function write(string $contents): self
26+
{
27+
$this->console->write($contents);
28+
29+
return $this;
30+
}
31+
32+
public function writeln(string $line = ''): self
33+
{
34+
$this->console->writeln($line);
35+
36+
return $this;
37+
}
38+
39+
/**
40+
* @param string $question
41+
* @param array|null $options
42+
* @param mixed|null $default
43+
* @param bool $multiple
44+
* @param bool $asList
45+
* @param \Tempest\Validation\Rule[] $validation
46+
* @return string|array
47+
*/
48+
public function ask(
49+
string $question,
50+
?array $options = null,
51+
mixed $default = null,
52+
bool $multiple = false,
53+
bool $asList = false,
54+
array $validation = [],
55+
): string|array {
56+
return $this->console->ask(
57+
question: $question,
58+
options: $options,
59+
default: $default,
60+
multiple: $multiple,
61+
asList: $asList,
62+
validation: $validation,
63+
);
64+
}
65+
66+
public function confirm(string $question, bool $default = false): bool
67+
{
68+
return $this->console->confirm(
69+
question: $question,
70+
default: $default,
71+
);
72+
}
73+
74+
public function password(string $label = 'Password', bool $confirm = false): string
75+
{
76+
return $this->console->password(
77+
label: $label,
78+
confirm: $confirm,
79+
);
80+
}
81+
82+
public function progressBar(iterable $data, Closure $handler): array
83+
{
84+
return $this->console->progressBar(
85+
data: $data,
86+
handler: $handler,
87+
);
88+
}
89+
90+
/**
91+
* @param string $label
92+
* @param Closure(string $search): array $search
93+
* @return mixed
94+
*/
95+
public function search(string $label, Closure $search): mixed
96+
{
97+
return $this->console->search(
98+
label: $label,
99+
search: $search,
100+
);
101+
}
102+
103+
public function info(string $line): self
104+
{
105+
$this->console->info($line);
106+
107+
return $this;
108+
}
109+
110+
public function error(string $line): self
111+
{
112+
$this->console->error($line);
113+
114+
return $this;
115+
}
116+
117+
public function success(string $line): self
118+
{
119+
$this->console->success($line);
120+
121+
return $this;
122+
}
123+
}

src/Input/ConsoleArgumentBag.php

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -34,16 +34,14 @@ public function __construct(array $arguments)
3434

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

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

4242
foreach ($flags as $flag) {
4343
$arguments[] = "-{$flag}";
4444
}
45-
46-
unset($arguments[$position]);
4745
}
4846
}
4947

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

108106
public function add(ConsoleInputArgument $argument): self
109107
{
110-
$this->arguments[] = $argument;
108+
$key = $argument->name ?? $argument->position;
109+
110+
$this->arguments[$key] = $argument->merge($this->arguments[$key] ?? null);
111111

112112
return $this;
113113
}

src/Input/ConsoleInputArgument.php

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@
44

55
namespace Tempest\Console\Input;
66

7+
use Tempest\Support\ArrayHelper;
8+
79
final class ConsoleInputArgument
810
{
911
public function __construct(
@@ -70,4 +72,17 @@ private static function parseNamedArgument(string $argument): array
7072

7173
return [$key, $value];
7274
}
75+
76+
public function merge(?ConsoleInputArgument $other): self
77+
{
78+
$clone = clone $this;
79+
80+
if ($other === null) {
81+
return $clone;
82+
}
83+
84+
$clone->value = array_values([...ArrayHelper::wrap($other->value), ...ArrayHelper::wrap($this->value)]);
85+
86+
return $clone;
87+
}
7388
}

src/Testing/ConsoleTester.php

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -147,6 +147,11 @@ public function useInteractiveTerminal(): self
147147
return $this;
148148
}
149149

150+
public function assertSee(string $text): self
151+
{
152+
return $this->assertContains($text);
153+
}
154+
150155
public function assertContains(string $text): self
151156
{
152157
Assert::assertStringContainsString(

tests/ConsoleArgumentBagTest.php

Lines changed: 24 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,12 +31,12 @@ public function test_argument_bag_works(): void
3131
$this->assertSame(0, $firstArg->position);
3232
$this->assertNull($firstArg->name);
3333

34-
$forceFlag = $bag->all()[1];
34+
$forceFlag = $bag->all()['force'];
3535
$this->assertSame(true, $forceFlag->value);
3636
$this->assertSame(null, $forceFlag->position);
3737
$this->assertSame('force', $forceFlag->name);
3838

39-
$timesFlag = $bag->all()[2];
39+
$timesFlag = $bag->all()['times'];
4040
$this->assertSame('2', $timesFlag->value);
4141
$this->assertSame(null, $timesFlag->position);
4242
$this->assertSame('times', $timesFlag->name);
@@ -69,4 +69,26 @@ public function test_short_flags_are_mapped_to_parameters_directly(): void
6969
->call('flags:short -ab')
7070
->assertContains('ok');
7171
}
72+
73+
public function test_array_input(): void
74+
{
75+
$argv = [
76+
'tempest',
77+
'test',
78+
'--input=a',
79+
'--input=b',
80+
'--input=c',
81+
];
82+
83+
$bag = new ConsoleArgumentBag($argv);
84+
85+
$this->assertSame(['a', 'b', 'c'], $bag->get('input')->value);
86+
}
87+
88+
public function test_array_input_to_command(): void
89+
{
90+
$this->console
91+
->call('array_input --input=a --input=b')
92+
->assertContains('["a","b"]');
93+
}
7294
}
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Tests\Tempest\Console\Fixtures;
6+
7+
use Tempest\Console\ConsoleCommand;
8+
use Tempest\Console\HasConsole;
9+
10+
final readonly class ArrayInputCommand
11+
{
12+
use HasConsole;
13+
14+
#[ConsoleCommand('array_input')]
15+
public function __invoke(array $input): void
16+
{
17+
$this->writeln(json_encode($input));
18+
}
19+
}

0 commit comments

Comments
 (0)