diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 189105d..2f3eecb 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -12,5 +12,3 @@ jobs: uses: innmind/github-workflows/.github/workflows/psalm-matrix.yml@main cs: uses: innmind/github-workflows/.github/workflows/cs.yml@main - with: - php-version: '8.2' diff --git a/.github/workflows/extensive.yml b/.github/workflows/extensive.yml new file mode 100644 index 0000000..257f139 --- /dev/null +++ b/.github/workflows/extensive.yml @@ -0,0 +1,12 @@ +name: Extensive CI + +on: + push: + tags: + - '*' + paths: + - '.github/workflows/extensive.yml' + +jobs: + blackbox: + uses: innmind/github-workflows/.github/workflows/extensive.yml@main diff --git a/CHANGELOG.md b/CHANGELOG.md index 6522d61..8aba27e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,14 @@ # Changelog +## [Unreleased] + +### Changed + +- Requires PHP `8.4` +- Commands name only support alphanumerical characters (use unicode at your own risk) +- `Innmind\CLI\Environment` is now a final class, all previous implementations are now flagged as internal +- Requires `innmind/operating-system:~7.0` + ## 4.0.0 - 2025-07-13 ### Added diff --git a/blackbox.php b/blackbox.php index 5c3ddce..486f49b 100644 --- a/blackbox.php +++ b/blackbox.php @@ -10,6 +10,10 @@ }; Application::new($argv) + ->when( + \getenv('BLACKBOX_SET_SIZE') !== false, + static fn(Application $app) => $app->scenariiPerProof((int) \getenv('BLACKBOX_SET_SIZE')), + ) ->disableMemoryLimit() ->when( \getenv('ENABLE_COVERAGE') !== false, diff --git a/composer.json b/composer.json index db664a8..07ca13b 100644 --- a/composer.json +++ b/composer.json @@ -15,13 +15,13 @@ "issues": "http://github.com/Innmind/CLI/issues" }, "require": { - "php": "~8.2", - "innmind/io": "~3.2", - "innmind/immutable": "~5.16", - "innmind/url": "~4.0", - "innmind/operating-system": "~6.0", - "innmind/stack-trace": "~4.0", - "innmind/validation": "~2.0" + "php": "~8.4", + "innmind/io": "~4.0", + "innmind/immutable": "~6.0", + "innmind/url": "~5.0", + "innmind/operating-system": "~7.0", + "innmind/stack-trace": "~5.0", + "innmind/validation": "~3.0" }, "autoload": { "psr-4": { @@ -34,7 +34,7 @@ } }, "require-dev": { - "innmind/static-analysis": "^1.2.1", + "innmind/static-analysis": "~1.3", "innmind/black-box": "^6.4.1", "innmind/coding-standard": "~2.0" } diff --git a/fixtures/thrower.php b/fixtures/thrower.php index 99ff478..be3515b 100755 --- a/fixtures/thrower.php +++ b/fixtures/thrower.php @@ -7,7 +7,6 @@ use Innmind\CLI\{ Main, Environment, - Exception\LogicException, }; use Innmind\OperatingSystem\OperatingSystem; use Innmind\Immutable\Attempt; @@ -15,6 +14,6 @@ new class extends Main { protected function main(Environment $env, OperatingSystem $os): Attempt { - throw new LogicException('waaat'); + throw new \LogicException('waaat'); } }; diff --git a/src/Command/Usage.php b/src/Command/Usage.php index fb61bb7..84b7483 100644 --- a/src/Command/Usage.php +++ b/src/Command/Usage.php @@ -358,7 +358,7 @@ public function toString(): string ->arguments ->map(static fn($argument) => ' '.$argument->toString()) ->map(Str::of(...)) - ->fold(new Concat) + ->fold(Concat::monoid) ->toString(); if ($this->pack->unwrap()) { @@ -369,7 +369,7 @@ public function toString(): string ->options ->map(static fn($argument) => ' '.$argument->toString()) ->map(Str::of(...)) - ->fold(new Concat) + ->fold(Concat::monoid) ->toString(); $string .= ' --help --no-interaction'; diff --git a/src/Environment.php b/src/Environment.php index b840b9f..2089f29 100644 --- a/src/Environment.php +++ b/src/Environment.php @@ -3,7 +3,13 @@ namespace Innmind\CLI; -use Innmind\CLI\Environment\ExitCode; +use Innmind\CLI\Environment\{ + ExitCode, + Implementation, + GlobalEnvironment, + InMemory, +}; +use Innmind\IO\IO; use Innmind\Url\Path; use Innmind\Immutable\{ Map, @@ -16,48 +22,130 @@ /** * @psalm-immutable */ -interface Environment +final class Environment { + private function __construct( + private Implementation $implementation, + ) { + } + + /** + * @internal + */ + public static function global(IO $io): self + { + return new self(GlobalEnvironment::of($io)); + } + + /** + * @internal + * + * @param list $input + * @param list $arguments + * @param list $variables + */ + public static function inMemory( + array $input, + bool $interactive, + array $arguments, + array $variables, + string $workingDirectory, + ): self { + return new self(InMemory::of( + $input, + $interactive, + $arguments, + $variables, + $workingDirectory, + )); + } + /** * True if the environment running the script is an interactive terminal */ - public function interactive(): bool; + public function interactive(): bool + { + return $this->implementation->interactive(); + } /** * @param ?positive-int $length * * @return array{Attempt, self} */ - public function read(?int $length = null): array; + public function read(?int $length = null): array + { + [$read, $implementation] = $this->implementation->read($length); + + return [$read, new self($implementation)]; + } /** * @return Attempt */ - public function output(Str $data): Attempt; + public function output(Str $data): Attempt + { + return $this + ->implementation + ->output($data) + ->map(static fn($implementation) => new self($implementation)); + } /** * @return Attempt */ - public function error(Str $data): Attempt; + public function error(Str $data): Attempt + { + return $this + ->implementation + ->error($data) + ->map(static fn($implementation) => new self($implementation)); + } /** * @return Sequence */ - public function arguments(): Sequence; + public function arguments(): Sequence + { + return $this->implementation->arguments(); + } /** * @return Map */ - public function variables(): Map; + public function variables(): Map + { + return $this->implementation->variables(); + } /** * @param int<0, 254> $code */ - public function exit(int $code): self; + public function exit(int $code): self + { + return new self($this->implementation->exit($code)); + } /** * @return Maybe */ - public function exitCode(): Maybe; - public function workingDirectory(): Path; + public function exitCode(): Maybe + { + return $this->implementation->exitCode(); + } + + public function workingDirectory(): Path + { + return $this->implementation->workingDirectory(); + } + + /** + * @internal + * + * @return Sequence + */ + public function outputted(): Sequence + { + return $this->implementation->outputted(); + } } diff --git a/src/Environment/GlobalEnvironment.php b/src/Environment/GlobalEnvironment.php index e17db19..8c55ff2 100644 --- a/src/Environment/GlobalEnvironment.php +++ b/src/Environment/GlobalEnvironment.php @@ -3,8 +3,7 @@ namespace Innmind\CLI\Environment; -use Innmind\CLI\Environment; -use Innmind\TimeContinuum\Period; +use Innmind\Time\Period; use Innmind\IO\{ IO, Streams\Stream\Read, @@ -21,8 +20,9 @@ /** * @psalm-immutable + * @internal */ -final class GlobalEnvironment implements Environment +final class GlobalEnvironment implements Implementation { /** * @param Output<'stdout'> $output @@ -180,4 +180,10 @@ public function workingDirectory(): Path { return $this->workingDirectory; } + + #[\Override] + public function outputted(): Sequence + { + return Sequence::of(); + } } diff --git a/src/Environment/Implementation.php b/src/Environment/Implementation.php new file mode 100644 index 0000000..369585d --- /dev/null +++ b/src/Environment/Implementation.php @@ -0,0 +1,68 @@ +, self} + */ + public function read(?int $length = null): array; + + /** + * @return Attempt + */ + public function output(Str $data): Attempt; + + /** + * @return Attempt + */ + public function error(Str $data): Attempt; + + /** + * @return Sequence + */ + public function arguments(): Sequence; + + /** + * @return Map + */ + public function variables(): Map; + + /** + * @param int<0, 254> $code + */ + public function exit(int $code): self; + + /** + * @return Maybe + */ + public function exitCode(): Maybe; + public function workingDirectory(): Path; + + /** + * @return Sequence + */ + public function outputted(): Sequence; +} diff --git a/src/Environment/InMemory.php b/src/Environment/InMemory.php index 467b0ae..fefb21f 100644 --- a/src/Environment/InMemory.php +++ b/src/Environment/InMemory.php @@ -3,7 +3,6 @@ namespace Innmind\CLI\Environment; -use Innmind\CLI\Environment; use Innmind\Url\Path; use Innmind\Immutable\{ Sequence, @@ -16,21 +15,20 @@ /** * Use this implementation for tests only * @psalm-immutable + * @internal */ -final class InMemory implements Environment +final class InMemory implements Implementation { /** * @param Sequence $input - * @param Sequence $output - * @param Sequence $error + * @param Sequence $outputted * @param Sequence $arguments * @param Map $variables * @param Maybe $exitCode */ private function __construct( private Sequence $input, - private Sequence $output, - private Sequence $error, + private Sequence $outputted, private bool $interactive, private Sequence $arguments, private Map $variables, @@ -57,7 +55,6 @@ public static function of( return new self( Sequence::of(...$input)->map(static fn($string) => Str::of($string, Str\Encoding::ascii)), Sequence::of(), - Sequence::of(), $interactive, Sequence::of(...$arguments), Map::of(...$variables), @@ -95,8 +92,7 @@ public function read(?int $length = null): array $data->attempt(static fn() => new \LogicException('No input data specified')), new self( $input, - $this->output, - $this->error, + $this->outputted, $this->interactive, $this->arguments, $this->variables, @@ -111,8 +107,10 @@ public function output(Str $data): Attempt { return Attempt::result(new self( $this->input, - ($this->output)($data->toEncoding(Str\Encoding::ascii)), - $this->error, + ($this->outputted)([ + $data->toEncoding(Str\Encoding::ascii), + 'output', + ]), $this->interactive, $this->arguments, $this->variables, @@ -126,8 +124,10 @@ public function error(Str $data): Attempt { return Attempt::result(new self( $this->input, - $this->output, - ($this->error)($data->toEncoding(Str\Encoding::ascii)), + ($this->outputted)([ + $data->toEncoding(Str\Encoding::ascii), + 'error', + ]), $this->interactive, $this->arguments, $this->variables, @@ -153,8 +153,7 @@ public function exit(int $code): self { return new self( $this->input, - $this->output, - $this->error, + $this->outputted, $this->interactive, $this->arguments, $this->variables, @@ -175,25 +174,9 @@ public function workingDirectory(): Path return $this->workingDirectory; } - /** - * @return list - */ - public function outputs(): array - { - return $this - ->output - ->map(static fn($string) => $string->toString()) - ->toList(); - } - - /** - * @return list - */ - public function errors(): array + #[\Override] + public function outputted(): Sequence { - return $this - ->error - ->map(static fn($string) => $string->toString()) - ->toList(); + return $this->outputted; } } diff --git a/src/Exception/EachRowMustBeOfSameSize.php b/src/Exception/EachRowMustBeOfSameSize.php deleted file mode 100644 index 32dc35e..0000000 --- a/src/Exception/EachRowMustBeOfSameSize.php +++ /dev/null @@ -1,8 +0,0 @@ -io()); + $env = Environment::global($config->io()); try { $env = $this->main($env, $os)->unwrap(); diff --git a/tests/Command/Pattern/InputsTest.php b/tests/Command/Pattern/InputsTest.php index 2511fdc..66eb447 100644 --- a/tests/Command/Pattern/InputsTest.php +++ b/tests/Command/Pattern/InputsTest.php @@ -18,6 +18,6 @@ public function testThrowWhenPatternNotRecognized() $this->expectException(PatternNotRecognized::class); $this->expectExceptionMessage('_foo_'); - (new Inputs)(Usage::of('name'), Str::of('_foo_'))->unwrap(); + $_ = (new Inputs)(Usage::of('name'), Str::of('_foo_'))->unwrap(); } } diff --git a/tests/Command/Pattern/OptionFlagTest.php b/tests/Command/Pattern/OptionFlagTest.php index 476d439..069f582 100644 --- a/tests/Command/Pattern/OptionFlagTest.php +++ b/tests/Command/Pattern/OptionFlagTest.php @@ -77,7 +77,7 @@ public function testParse() ); $this->assertSame(['watev', 'bar', '--unknown', 'baz'], $arguments->toList()); - $this->assertCount(1, $options); + $this->assertSame(1, $options->size()); $this->assertSame('', $options->get('foo')->match( static fn($value) => $value, static fn() => null, diff --git a/tests/Command/Pattern/OptionWithValueTest.php b/tests/Command/Pattern/OptionWithValueTest.php index a63c5df..d711257 100644 --- a/tests/Command/Pattern/OptionWithValueTest.php +++ b/tests/Command/Pattern/OptionWithValueTest.php @@ -77,7 +77,7 @@ public function testParseShortOption() ); $this->assertSame(['watev', 'bar'], $arguments->toList()); - $this->assertCount(1, $options); + $this->assertSame(1, $options->size()); $this->assertSame('baz', $options->get('foo')->match( static fn($value) => $value, static fn() => null, @@ -97,7 +97,7 @@ public function testParseShortOptionWithValueInNextArgument() ); $this->assertSame(['watev', 'bar'], $arguments->toList()); - $this->assertCount(1, $options); + $this->assertSame(1, $options->size()); $this->assertSame('baz', $options->get('foo')->match( static fn($value) => $value, static fn() => null, @@ -117,7 +117,7 @@ public function testParseShortOptionWithValueInNextArgumentButNoNextValue() ); $this->assertSame(['watev'], $arguments->toList()); - $this->assertCount(1, $options); + $this->assertSame(1, $options->size()); $this->assertSame('', $options->get('foo')->match( static fn($value) => $value, static fn() => null, @@ -137,7 +137,7 @@ public function testParseLongOption() ); $this->assertSame(['watev', 'bar'], $arguments->toList()); - $this->assertCount(1, $options); + $this->assertSame(1, $options->size()); $this->assertSame('baz', $options->get('foo')->match( static fn($value) => $value, static fn() => null, diff --git a/tests/Command/Pattern/OptionalArgumentTest.php b/tests/Command/Pattern/OptionalArgumentTest.php index 302a84c..d9da036 100644 --- a/tests/Command/Pattern/OptionalArgumentTest.php +++ b/tests/Command/Pattern/OptionalArgumentTest.php @@ -79,7 +79,7 @@ public function testParse(): BlackBox\Proof Map::of(), ); - $this->assertCount(1, $parsedArguments); + $this->assertSame(1, $parsedArguments->size()); $this->assertSame($strings[0], $parsedArguments->get('foo')->match( static fn($value) => $value, static fn() => null, @@ -104,7 +104,7 @@ public function testParseWhenNoMoreArguments() Map::of(), ); - $this->assertCount(0, $parsedArguments); + $this->assertSame(0, $parsedArguments->size()); $this->assertNull($parsedArguments->get('foo')->match( static fn($value) => $value, static fn() => null, diff --git a/tests/Command/Pattern/RequiredArgumentTest.php b/tests/Command/Pattern/RequiredArgumentTest.php index 0d84f80..240cca8 100644 --- a/tests/Command/Pattern/RequiredArgumentTest.php +++ b/tests/Command/Pattern/RequiredArgumentTest.php @@ -80,7 +80,7 @@ public function testParse(): BlackBox\Proof Map::of(), ); - $this->assertCount(1, $parsedArguments); + $this->assertSame(1, $parsedArguments->size()); $this->assertSame($strings[0], $parsedArguments->get('foo')->match( static fn($value) => $value, static fn() => null, diff --git a/tests/Command/PatternTest.php b/tests/Command/PatternTest.php index 33e9fd0..4bcfe77 100644 --- a/tests/Command/PatternTest.php +++ b/tests/Command/PatternTest.php @@ -67,6 +67,6 @@ public function testParse() $this->assertSame('first', $arguments->get('foo')); $this->assertSame('second', $arguments->get('bar')); - $this->assertCount(0, $arguments->pack()); + $this->assertSame(0, $arguments->pack()->size()); } } diff --git a/tests/Command/UsageTest.php b/tests/Command/UsageTest.php index a82483b..1f36da0 100644 --- a/tests/Command/UsageTest.php +++ b/tests/Command/UsageTest.php @@ -55,6 +55,7 @@ public function testMatchesItsOwnName(): BlackBox\Proof $this->names(), ) ->filter(static fn($a, $b) => $a !== $b) + ->filter(static fn($a, $b) => !\str_starts_with($a, $b)) ->prove(function($a, $b) { $usage = Usage::parse($a); @@ -135,6 +136,10 @@ public function testDoesntMatchWhenOwnNameDoesntExplicitlyStartWithSubset(): Bla Set::integers()->between(1, 10), Set::integers()->between(1, 10), ) + ->filter(static fn($name, $start, $shrink) => !\str_starts_with( + $name, + \mb_substr($name, $start, $shrink), + )) ->prove(function($name, $start, $shrink) { $usage = Usage::parse($name); $shrunk = \mb_substr($name, $start, $shrink); @@ -156,23 +161,8 @@ private function names(): Set return Set::strings() ->madeOf( Set::strings() - ->unicode() - ->char() - ->filter( - static fn($char) => !\in_array( - $char, - [ - ':', - ' ', - "\n", - "\r", - \chr(11), - \chr(0), - "\t", - ], - true, - ), - ), + ->chars() + ->alphanumerical(), ) ->between(1, 10); } diff --git a/tests/CommandsTest.php b/tests/CommandsTest.php index 7afc51a..bb9afba 100644 --- a/tests/CommandsTest.php +++ b/tests/CommandsTest.php @@ -55,7 +55,7 @@ public function usage(): Usage return Usage::parse('watch container [output] --foo'); } }); - $env = Environment\InMemory::of( + $env = Environment::inMemory( [], true, ['bin/console', 'foo', '--foo', 'bar'], @@ -105,7 +105,7 @@ public function usage(): Usage } }, ); - $env = Environment\InMemory::of( + $env = Environment::inMemory( [], true, ['bin/console', 'watch', 'foo', '--foo', 'bar'], @@ -145,7 +145,7 @@ public function usage(): Usage } }, ); - $env = Environment\InMemory::of( + $env = Environment::inMemory( [], true, ['bin/console', 'watch', 'foo', '--foo', 'bar'], @@ -185,7 +185,7 @@ public function usage(): Usage } }, ); - $env = Environment\InMemory::of( + $env = Environment::inMemory( [], true, ['bin/console', 'foo'], @@ -225,7 +225,7 @@ public function usage(): Usage } }, ); - $env = Environment\InMemory::of( + $env = Environment::inMemory( [], true, ['bin/console', 'w'], @@ -265,7 +265,7 @@ public function usage(): Usage } }, ); - $env = Environment\InMemory::of( + $env = Environment::inMemory( [], true, ['bin/console', 'f:b:b'], @@ -305,7 +305,7 @@ public function usage(): Usage } }, ); - $env = Environment\InMemory::of( + $env = Environment::inMemory( [], true, ['bin/console', 'bar'], @@ -324,7 +324,11 @@ public function usage(): Usage " foo \n", " watch \n", ], - $env->errors(), + $env + ->outputted() + ->filter(static fn($pair) => $pair[1] === 'error') + ->map(static fn($pair) => $pair[0]->toString()) + ->toList(), ); } @@ -354,7 +358,7 @@ public function usage(): Usage } }, ); - $env = Environment\InMemory::of( + $env = Environment::inMemory( [], true, ['bin/console', 'ba'], @@ -373,7 +377,11 @@ public function usage(): Usage " bar \n", " baz \n", ], - $env->errors(), + $env + ->outputted() + ->filter(static fn($pair) => $pair[1] === 'error') + ->map(static fn($pair) => $pair[0]->toString()) + ->toList(), ); } @@ -396,7 +404,7 @@ public function usage(): Usage USAGE); } }); - $env = Environment\InMemory::of( + $env = Environment::inMemory( [], true, ['bin/console'], @@ -412,7 +420,11 @@ public function usage(): Usage )); $this->assertSame( ['usage: bin/console watch container [output] --foo --help --no-interaction'."\n\nFoo\n\nBar\n"], - $env->errors(), + $env + ->outputted() + ->filter(static fn($pair) => $pair[1] === 'error') + ->map(static fn($pair) => $pair[0]->toString()) + ->toList(), ); } @@ -429,7 +441,7 @@ public function usage(): Usage return Usage::parse('watch container [output] --foo'); } }); - $env = Environment\InMemory::of( + $env = Environment::inMemory( [], true, ['bin/console', 'foo', '--foo', 'bar'], @@ -439,7 +451,7 @@ public function usage(): Usage $this->expectException(\Exception::class); - $run($env)->unwrap(); + $_ = $run($env)->unwrap(); } public function testDisplayUsageWhenHelpOptionFound() @@ -461,7 +473,7 @@ public function usage(): Usage USAGE); } }); - $env = Environment\InMemory::of( + $env = Environment::inMemory( [], true, ['bin/console', '--help'], @@ -477,7 +489,11 @@ public function usage(): Usage )); $this->assertSame( ['usage: bin/console watch container [output] --foo --help --no-interaction'."\n\nFoo\n\nBar\n"], - $env->outputs(), + $env + ->outputted() + ->filter(static fn($pair) => $pair[1] === 'output') + ->map(static fn($pair) => $pair[0]->toString()) + ->toList(), ); } @@ -507,7 +523,7 @@ public function usage(): Usage } }, ); - $env = Environment\InMemory::of( + $env = Environment::inMemory( [], true, ['bin/console', 'help'], @@ -526,7 +542,11 @@ public function usage(): Usage " foo Description\n", " watch Watch dependency injection\n", ], - $env->outputs(), + $env + ->outputted() + ->filter(static fn($pair) => $pair[1] === 'output') + ->map(static fn($pair) => $pair[0]->toString()) + ->toList(), ); } @@ -556,7 +576,7 @@ public function usage(): Usage } }, ); - $env = Environment\InMemory::of( + $env = Environment::inMemory( [], true, ['bin/console'], @@ -572,7 +592,11 @@ public function usage(): Usage )); $this->assertSame( [" foo \n", " watch \n"], - $env->errors(), + $env + ->outputted() + ->filter(static fn($pair) => $pair[1] === 'error') + ->map(static fn($pair) => $pair[0]->toString()) + ->toList(), ); } @@ -603,7 +627,7 @@ public function usage(): Usage } }, ); - $env = Environment\InMemory::of( + $env = Environment::inMemory( [], true, ['bin/console', 'help'], @@ -622,7 +646,11 @@ public function usage(): Usage " foo \n", " watch \n", ], - $env->outputs(), + $env + ->outputted() + ->filter(static fn($pair) => $pair[1] === 'output') + ->map(static fn($pair) => $pair[0]->toString()) + ->toList(), ); } @@ -647,7 +675,7 @@ public function usage(): Usage } }, ); - $env = Environment\InMemory::of( + $env = Environment::inMemory( [], true, ['bin/console', '--help'], @@ -670,7 +698,11 @@ public function usage(): Usage USAGE, ], - $env->outputs(), + $env + ->outputted() + ->filter(static fn($pair) => $pair[1] === 'output') + ->map(static fn($pair) => $pair[0]->toString()) + ->toList(), ); } @@ -713,7 +745,7 @@ public function usage(): Usage } }; })); - $env = Environment\InMemory::of( + $env = Environment::inMemory( [], true, ['bin/console', 'watch', 'foo', '--foo', 'bar'], @@ -784,7 +816,7 @@ public function usage(): Usage } }; })); - $env = Environment\InMemory::of( + $env = Environment::inMemory( [], true, ['bin/console', 'ba'], @@ -856,7 +888,7 @@ public function usage(): Usage } }; })); - $env = Environment\InMemory::of( + $env = Environment::inMemory( [], true, ['bin/console', 'unknown'], diff --git a/tests/Environment/GlobalEnvironmentTest.php b/tests/Environment/GlobalEnvironmentTest.php index 108bc66..7b4b71b 100644 --- a/tests/Environment/GlobalEnvironmentTest.php +++ b/tests/Environment/GlobalEnvironmentTest.php @@ -3,10 +3,7 @@ namespace Tests\Innmind\CLI\Environment; -use Innmind\CLI\{ - Environment\GlobalEnvironment, - Environment, -}; +use Innmind\CLI\Environment\GlobalEnvironment; use Innmind\IO\IO; use Innmind\Url\Path; use Innmind\Immutable\{ @@ -25,11 +22,6 @@ public function setUp(): void $this->env = GlobalEnvironment::of(IO::fromAmbientAuthority()); } - public function testInterface() - { - $this->assertInstanceOf(Environment::class, $this->env); - } - public function testInteractive() { // can't prove via a test that the env can be interactive as tests are @@ -63,7 +55,6 @@ public function testExitCode() { $this->assertEquals(Maybe::nothing(), $this->env->exitCode()); $env = $this->env->exit(1); - $this->assertInstanceOf(Environment::class, $env); $this->assertSame(1, $env->exitCode()->match( static fn($code) => $code->toInt(), static fn() => null, diff --git a/tests/MainTest.php b/tests/MainTest.php index 0af3b68..842b4ff 100644 --- a/tests/MainTest.php +++ b/tests/MainTest.php @@ -72,7 +72,7 @@ public function testEcho() $process ->output() ->map(static fn($chunk) => $chunk->data()) - ->fold(new Concat) + ->fold(Concat::monoid) ->toString(), ); } @@ -88,7 +88,7 @@ public function testThrow() ->withEnvironment('PATH', $_SERVER['PATH']), ) ->unwrap(); - $process->output()->foreach(function($chunk): void { + $_ = $process->output()->foreach(function($chunk): void { $this->assertSame(Type::error, $chunk->type()); }); @@ -97,7 +97,7 @@ public function testThrow() $process ->output() ->map(static fn($chunk) => $chunk->data()) - ->fold(new Concat) + ->fold(Concat::monoid) ->toString(), ) ->split("\n") @@ -105,11 +105,11 @@ public function testThrow() $this->assertCount(6, $output); $this->assertSame( - "Innmind\CLI\Exception\LogicException(waaat, 0)", + 'LogicException(waaat, 0)', $output[0]->toString(), ); $this->assertSame( - "$cwd/fixtures/thrower.php:18", + "$cwd/fixtures/thrower.php:17", $output[1]->toString(), ); $this->assertSame( @@ -133,7 +133,7 @@ public function testThrow() $output[3]->substring(-28 - \strlen($cwd))->toString(), ); $this->assertSame( - "Innmind\CLI\Main->__construct() at $cwd/fixtures/thrower.php:15", + "Innmind\CLI\Main->__construct() at $cwd/fixtures/thrower.php:14", $output[4]->toString(), ); $this->assertSame( diff --git a/tests/Question/ChoiceQuestionTest.php b/tests/Question/ChoiceQuestionTest.php index 123d6ea..75197db 100644 --- a/tests/Question/ChoiceQuestionTest.php +++ b/tests/Question/ChoiceQuestionTest.php @@ -22,7 +22,7 @@ public function testInvoke() (2, 3) ('bar', 3), ); - $env = Environment\InMemory::of( + $env = Environment::inMemory( [' foo, ', "2\n"], true, [], @@ -37,7 +37,7 @@ public function testInvoke() ); $this->assertInstanceOf(Map::class, $response); - $this->assertCount(2, $response); + $this->assertSame(2, $response->size()); $this->assertSame('bar', $response->get('foo')->match( static fn($value) => $value, static fn() => null, @@ -55,7 +55,10 @@ public function testInvoke() "[bar] 3\n", '> ', ], - $env->outputs(), + $env + ->outputted() + ->map(static fn($pair) => $pair[0]->toString()) + ->toList(), ); } @@ -63,7 +66,7 @@ public function testReturnNothingWhenEnvNonInteractive() { $question = ChoiceQuestion::of('watev', Map::of()); - $env = Environment\InMemory::of( + $env = Environment::inMemory( [], false, [], @@ -83,7 +86,7 @@ public function testReturnNothingWhenOptionToSpecifyNoInteractionIsRequired() { $question = ChoiceQuestion::of('watev', Map::of()); - $env = Environment\InMemory::of( + $env = Environment::inMemory( [], true, ['foo', '--no-interaction', 'bar'], diff --git a/tests/Question/QuestionTest.php b/tests/Question/QuestionTest.php index 9f0bd1b..f968ea1 100644 --- a/tests/Question/QuestionTest.php +++ b/tests/Question/QuestionTest.php @@ -15,7 +15,7 @@ class QuestionTest extends TestCase public function testInvoke() { $question = Question::of('message'); - $env = Environment\InMemory::of( + $env = Environment::inMemory( ['f', "oo\n"], true, [], @@ -33,7 +33,10 @@ public function testInvoke() $this->assertSame('foo', $response->toString()); $this->assertSame( ['message '], - $env->outputs(), + $env + ->outputted() + ->map(static fn($pair) => $pair[0]->toString()) + ->toList(), ); } @@ -41,7 +44,7 @@ public function testReturnNothingWhenEnvNonInteractive() { $question = Question::of('watev'); - $env = Environment\InMemory::of( + $env = Environment::inMemory( [], false, [], @@ -61,7 +64,7 @@ public function testReturnNothingWhenOptionToSpecifyNoInteractionIsRequired() { $question = Question::of('watev'); - $env = Environment\InMemory::of( + $env = Environment::inMemory( [], true, ['foo', '--no-interaction', 'bar'],