Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
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
20 changes: 15 additions & 5 deletions src/Functions/console.php
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,9 @@ function readLine(string $prompt, $stream = null): IO
*/
function printError(string $message): IO
{
return new IO(fn () => print("\033[31mError: {$message}\033[0m" . PHP_EOL));
return new IO(function () use ($message): void {
print("\033[31mError: {$message}\033[0m" . PHP_EOL);
});
}

const printWarning = '\Phunkie\Effect\Functions\console\printWarning';
Expand All @@ -92,7 +94,9 @@ function printError(string $message): IO
*/
function printWarning(string $message): IO
{
return new IO(fn () => print("\033[33mWarning: {$message}\033[0m" . PHP_EOL));
return new IO(function () use ($message): void {
print("\033[33mWarning: {$message}\033[0m" . PHP_EOL);
});
}

const printSuccess = '\Phunkie\Effect\Functions\console\printSuccess';
Expand All @@ -105,7 +109,9 @@ function printWarning(string $message): IO
*/
function printSuccess(string $message): IO
{
return new IO(fn () => print("\033[32mSuccess: {$message}\033[0m" . PHP_EOL));
return new IO(function () use ($message): void {
print("\033[32mSuccess: {$message}\033[0m" . PHP_EOL);
});
}

const printInfo = '\Phunkie\Effect\Functions\console\printInfo';
Expand All @@ -118,7 +124,9 @@ function printSuccess(string $message): IO
*/
function printInfo(string $message): IO
{
return new IO(fn () => print("\033[36mInfo: {$message}\033[0m" . PHP_EOL));
return new IO(function () use ($message): void {
print("\033[36mInfo: {$message}\033[0m" . PHP_EOL);
});
}

const printDebug = '\Phunkie\Effect\Functions\console\printDebug';
Expand All @@ -131,7 +139,9 @@ function printInfo(string $message): IO
*/
function printDebug(string $message): IO
{
return new IO(fn () => print("\033[35mDebug: {$message}\033[0m" . PHP_EOL));
return new IO(function () use ($message): void {
print("\033[35mDebug: {$message}\033[0m" . PHP_EOL);
});
}

const printTable = '\Phunkie\Effect\Functions\console\printTable';
Expand Down
8 changes: 6 additions & 2 deletions src/IO/IOApp/OptionDefinition.php
Original file line number Diff line number Diff line change
Expand Up @@ -56,8 +56,12 @@ public function __construct(string $p1, string|null $p2 = null, string|OptionFor
}
}

if ($short === null && $long === null) {
throw new \InvalidArgumentException("At least one of short or long name must be provided");
// Emptiness rather than absence: the name is a required string and every
// branch above assigns it to one of the two, so neither can be null and
// a test for that never fired. What it meant to catch is an option no
// one could ever pass.
if (($short ?? '') === '' && ($long ?? '') === '') {
throw new \InvalidArgumentException('At least one of short or long name must be provided.');
}

$this->short = $short;
Expand Down
13 changes: 13 additions & 0 deletions tests/Unit/IO/IOApp/OptionsTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,19 @@ public function test_it_creates_options_with_mixed_definitions()
$this->assertInstanceOf(Options::class, $validation->toOption()->get());
}

// An option has to be callable by something. The guard for that could never
// fire, because the name is a required string and every branch assigns it,
// so an option with no usable name was handed back as if it were fine.
public function test_it_refuses_an_option_with_no_name()
{
$this->assertTrue(option('')->isLeft());
}

public function test_it_accepts_an_option_named_only_by_its_long_form()
{
$this->assertTrue(option('', 'verbose', 'Verbose', NoInput)->isRight());
}

public function test_it_parses_short_flags()
{
$options = arguments(
Expand Down
Loading