From 1b9da1af0d4503a59798c581a464caa489cd6a36 Mon Sep 17 00:00:00 2001 From: Baptiste Langlade Date: Sun, 22 Feb 2026 17:16:14 +0100 Subject: [PATCH 1/5] update dependencies --- .github/workflows/ci.yml | 2 +- CHANGELOG.md | 7 + composer.json | 11 +- src/Activities.php | 7 +- src/Command/Work.php | 12 +- src/Iteration.php | 2 +- src/Monitor.php | 21 +- src/Monitor/Loop.php | 26 +- src/Trigger/BlackBox.php | 15 +- src/Trigger/CodingStandard.php | 19 +- src/Trigger/ComposerUpdate.php | 17 +- src/Trigger/DockerCompose.php | 7 +- src/Trigger/Psalm.php | 15 +- src/Trigger/Tests.php | 15 +- tests/Agent/WatchFixturesTest.php | 65 +-- tests/Agent/WatchProofsTest.php | 65 +-- tests/Agent/WatchPropertiesTest.php | 65 +-- tests/Agent/WatchSourcesTest.php | 39 +- tests/Agent/WatchTestsTest.php | 59 +-- tests/BootstrapTest.php | 2 +- tests/Command/WorkTest.php | 8 +- tests/IterationTest.php | 57 ++- tests/Trigger/AllTest.php | 10 +- tests/Trigger/BlackBoxTest.php | 497 +++++++++------------- tests/Trigger/CodingStandardTest.php | 605 +++++++++++---------------- tests/Trigger/ComposerUpdateTest.php | 107 +++-- tests/Trigger/DockerComposeTest.php | 134 +++--- tests/Trigger/PsalmTest.php | 486 +++++++++------------ tests/Trigger/TestsTest.php | 511 +++++++++------------- 29 files changed, 1184 insertions(+), 1702 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 619283c..adb8ae9 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -8,7 +8,7 @@ jobs: strategy: matrix: os: [ubuntu-latest, macOS-latest] - php-version: ['8.2', '8.3', '8.4'] + php-version: ['8.4', '8.5'] dependencies: ['lowest', 'highest'] name: 'PHPUnit' steps: diff --git a/CHANGELOG.md b/CHANGELOG.md index bb65d65..4ebd5ca 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,12 @@ # Changelog +## [Unreleased] + +### Changed + +- Requires PHP `8.4` +- Requires `innmind/foundation:~2.1` + ## 4.2.0 - 2025-02-09 ### Added diff --git a/composer.json b/composer.json index 7b564e2..e63e3b6 100644 --- a/composer.json +++ b/composer.json @@ -15,13 +15,8 @@ "issues": "http://github.com/Innmind/LabStation/issues" }, "require": { - "php": "~8.2", - "innmind/url": "~4.0", - "innmind/cli": "~3.4", - "innmind/operating-system": "~5.0", - "innmind/json": "^1.1", - "innmind/immutable": "~5.2", - "innmind/mantle": "~2.0" + "php": "~8.4", + "innmind/foundation": "~2.1" }, "autoload": { "psr-4": { @@ -36,7 +31,7 @@ }, "require-dev": { "phpunit/phpunit": "~10.2", - "innmind/static-analysis": "^1.2.1", + "innmind/static-analysis": "~1.3", "innmind/black-box": "~6.5", "innmind/coding-standard": "~2.0" }, diff --git a/src/Activities.php b/src/Activities.php index a8aa66d..4ba4609 100644 --- a/src/Activities.php +++ b/src/Activities.php @@ -5,7 +5,7 @@ use Innmind\CLI\Console; use Innmind\OperatingSystem\OperatingSystem; -use Innmind\TimeContinuum\Earth\Period\Millisecond; +use Innmind\Time\Period; use Innmind\Immutable\Set; final class Activities @@ -46,7 +46,10 @@ public function __invoke( // exit this method periodically to allow the source to be restarted in // order to check if any agent crashed in order to restart it. if (\count($this->activities) === 0) { - $os->process()->halt(Millisecond::of(500)); + $_ = $os + ->process() + ->halt(Period::millisecond(500)) + ->unwrap(); } while ($activity = \array_shift($this->activities)) { diff --git a/src/Command/Work.php b/src/Command/Work.php index ca0ff95..d95f197 100644 --- a/src/Command/Work.php +++ b/src/Command/Work.php @@ -9,9 +9,11 @@ }; use Innmind\CLI\{ Command, + Command\Usage, Console, }; use Innmind\Immutable\{ + Attempt, Str, Set, }; @@ -26,7 +28,7 @@ public function __construct(Monitor $monitor) } #[\Override] - public function __invoke(Console $console): Console + public function __invoke(Console $console): Attempt { $triggers = $console ->options() @@ -44,21 +46,21 @@ public function __invoke(Console $console): Console static fn() => Triggers::cases(), ); - return ($this->monitor)($console, Set::of(...$triggers)); + return Attempt::result(($this->monitor)($console, Set::of(...$triggers))); } /** * @psalm-pure */ #[\Override] - public function usage(): string + public function usage(): Usage { - return <<output(Str::of("\033[2J\033[H")); + return $console->output(Str::of("\033[2J\033[H"))->unwrap(); } } diff --git a/src/Monitor.php b/src/Monitor.php index b84304e..5bf99cc 100644 --- a/src/Monitor.php +++ b/src/Monitor.php @@ -5,7 +5,7 @@ use Innmind\CLI\Console; use Innmind\OperatingSystem\OperatingSystem; -use Innmind\Mantle\Forerunner; +use Innmind\Async\Scheduler; use Innmind\Immutable\{ Set, Sequence, @@ -40,7 +40,7 @@ public function __construct( public function __invoke(Console $console, Set $triggers): Console { $project = $console->workingDirectory(); - $run = Forerunner::of($this->os); + $scheduler = Scheduler::of($this->os); $activities = Activities::new( $this->trigger, $this->iteration, @@ -49,14 +49,15 @@ public function __invoke(Console $console, Set $triggers): Console /** @var array{Console, boolean} */ $carry = [$console, false]; - [$console] = $run( - $carry, - new Monitor\Loop( - $this->agents, - $activities, - $project, - ), - ); + [$console] = $scheduler + ->sink($carry) + ->with( + new Monitor\Loop( + $this->agents, + $activities, + $project, + ), + ); return $console; } diff --git a/src/Monitor/Loop.php b/src/Monitor/Loop.php index 0b12c67..6a3d0e6 100644 --- a/src/Monitor/Loop.php +++ b/src/Monitor/Loop.php @@ -7,10 +7,7 @@ Agent, Activities, }; -use Innmind\Mantle\{ - Source\Continuation, - Task, -}; +use Innmind\Async\Scope\Continuation; use Innmind\CLI\Console; use Innmind\OperatingSystem\OperatingSystem; use Innmind\Url\Path; @@ -41,27 +38,26 @@ public function __construct( /** * @param array{Console, boolean} $carry - * @param Continuation $continuation - * @param Sequence $crashed + * @param Continuation $continuation * - * @return Continuation + * @return Continuation */ public function __invoke( array $carry, OperatingSystem $os, Continuation $continuation, - Sequence $crashed, ): Continuation { [$console, $started] = $carry; if (!$started) { return $continuation - ->launch($this->agents->map($this->buildTask(...))) + ->schedule($this->agents->map($this->buildTask(...))) ->carryWith([$console, true]); } - $continuation = $continuation->launch( - $crashed + $continuation = $continuation->schedule( + $continuation + ->results() // crashed agents ->keep(Instance::of(Agent::class)) ->map($this->buildTask(...)), ); @@ -75,14 +71,14 @@ public function __invoke( } /** - * @return Task + * @return callable(OperatingSystem): ?Agent */ - private function buildTask(Agent $agent): Task + private function buildTask(Agent $agent): callable { - return Task::of(fn($os) => $agent( + return fn(OperatingSystem $os) => $agent( $os, $this->project, $this->activities, - )); + ); } } diff --git a/src/Trigger/BlackBox.php b/src/Trigger/BlackBox.php index 6889c82..bd71a9b 100644 --- a/src/Trigger/BlackBox.php +++ b/src/Trigger/BlackBox.php @@ -52,6 +52,7 @@ private function attempt(Console $console, OperatingSystem $os): Console return $os ->filesystem() ->mount($console->workingDirectory()) + ->unwrap() ->get(Name::of('blackbox.php')) ->match( fn() => $this->run($console, $os), @@ -79,13 +80,14 @@ private function run(Console $console, OperatingSystem $os): Console ->withArgument('blackbox.php') ->withWorkingDirectory($console->workingDirectory()) ->withEnvironments($variables), - ); + ) + ->unwrap(); $console = $process ->output() - ->reduce( - $console, - static fn(Console $console, $line) => $console->output($line), - ); + ->map(static fn($chunk) => $chunk->data()) + ->sink($console) + ->attempt(static fn(Console $console, $line) => $console->output($line)) + ->unwrap(); $successful = $process->wait()->match( static fn() => true, static fn() => false, @@ -110,7 +112,8 @@ private function run(Console $console, OperatingSystem $os): Console }, ), ) - ->wait() + ->either() + ->flatMap(static fn($process) => $process->wait()) ->match( static fn() => $console, static fn() => $console, diff --git a/src/Trigger/CodingStandard.php b/src/Trigger/CodingStandard.php index f1cadc5..c002a3b 100644 --- a/src/Trigger/CodingStandard.php +++ b/src/Trigger/CodingStandard.php @@ -50,7 +50,10 @@ public function __invoke( private function attempt(Console $console, OperatingSystem $os): Console { - $directory = $os->filesystem()->mount($console->workingDirectory()); + $directory = $os + ->filesystem() + ->mount($console->workingDirectory()) + ->unwrap(); return $directory ->get(Name::of('.php_cs.dist')) @@ -91,13 +94,14 @@ private function run( $process = $os ->control() ->processes() - ->execute($command); + ->execute($command) + ->unwrap(); $console = $process ->output() - ->reduce( - $console, - static fn(Console $console, $line) => $console->output($line), - ); + ->map(static fn($chunk) => $chunk->data()) + ->sink($console) + ->attempt(static fn(Console $console, $line) => $console->output($line)) + ->unwrap(); $successful = $process->wait()->match( static fn() => true, static fn() => false, @@ -122,7 +126,8 @@ private function run( }, ), ) - ->wait() + ->either() + ->flatMap(static fn($process) => $process->wait()) ->match( static fn() => $console, static fn() => $console, diff --git a/src/Trigger/ComposerUpdate.php b/src/Trigger/ComposerUpdate.php index 64938be..5b22282 100644 --- a/src/Trigger/ComposerUpdate.php +++ b/src/Trigger/ComposerUpdate.php @@ -41,10 +41,11 @@ public function __invoke( private function ask(Console $console, OperatingSystem $os): Console { - $ask = new Question('Update dependencies? [Y/n]'); - [$response, $console] = $ask($console); + $ask = Question::of('Update dependencies? [Y/n]'); + [$response, $console] = $ask($console)->unwrap(); return $response + ->maybe() ->filter(static fn($response) => match ($response->toString()) { 'y', '' => true, default => false, @@ -72,11 +73,13 @@ private function run(Console $console, OperatingSystem $os): Console ->withWorkingDirectory($console->workingDirectory()) ->withEnvironments($variables), ) + ->unwrap() ->output() - ->reduce( - $console, - static fn(Console $console, $line) => $console->output($line), - ) - ->output(Str::of("Dependencies updated!\n")); + ->map(static fn($chunk) => $chunk->data()) + ->sink($console) + ->attempt(static fn(Console $console, $line) => $console->output($line)) + ->unwrap() + ->output(Str::of("Dependencies updated!\n")) + ->unwrap(); } } diff --git a/src/Trigger/DockerCompose.php b/src/Trigger/DockerCompose.php index 377da09..ee6871f 100644 --- a/src/Trigger/DockerCompose.php +++ b/src/Trigger/DockerCompose.php @@ -42,6 +42,7 @@ private function attempt(Console $console, OperatingSystem $os): Console return $os ->filesystem() ->mount($console->workingDirectory()) + ->unwrap() ->get(Name::of('docker-compose.yml')) ->match( fn() => $this->run($console, $os), @@ -66,11 +67,13 @@ private function run(Console $console, OperatingSystem $os): Console ->withWorkingDirectory($console->workingDirectory()) ->withEnvironments($variables), ) - ->wait() + ->either() + ->flatMap(static fn($process) => $process->wait()) ->match( static fn() => $console, static fn() => $console - ->error(Str::of("Failed to start docker\n")), + ->error(Str::of("Failed to start docker\n")) + ->unwrap(), ); } } diff --git a/src/Trigger/Psalm.php b/src/Trigger/Psalm.php index 485ea52..fad32ce 100644 --- a/src/Trigger/Psalm.php +++ b/src/Trigger/Psalm.php @@ -49,6 +49,7 @@ private function attempt(Console $console, OperatingSystem $os): Console return $os ->filesystem() ->mount($console->workingDirectory()) + ->unwrap() ->get(Name::of('psalm.xml')) ->match( fn() => $this->run($console, $os), @@ -71,13 +72,14 @@ private function run(Console $console, OperatingSystem $os): Console ->withOption('no-cache') ->withWorkingDirectory($console->workingDirectory()) ->withEnvironments($variables), - ); + ) + ->unwrap(); $console = $process ->output() - ->reduce( - $console, - static fn(Console $console, $line) => $console->output($line), - ); + ->map(static fn($chunk) => $chunk->data()) + ->sink($console) + ->attempt(static fn(Console $console, $line) => $console->output($line)) + ->unwrap(); $successful = $process->wait()->match( static fn() => true, static fn() => false, @@ -102,7 +104,8 @@ private function run(Console $console, OperatingSystem $os): Console }, ), ) - ->wait() + ->either() + ->flatMap(static fn($process) => $process->wait()) ->match( static fn() => $console, static fn() => $console, diff --git a/src/Trigger/Tests.php b/src/Trigger/Tests.php index f157484..061ecbd 100644 --- a/src/Trigger/Tests.php +++ b/src/Trigger/Tests.php @@ -51,6 +51,7 @@ private function attempt(Console $console, OperatingSystem $os): Console return $os ->filesystem() ->mount($console->workingDirectory()) + ->unwrap() ->get(Name::of('phpunit.xml.dist')) ->match( fn() => $this->run($console, $os), @@ -74,13 +75,14 @@ private function run(Console $console, OperatingSystem $os): Console ->withOption('fail-on-warning') ->withWorkingDirectory($console->workingDirectory()) ->withEnvironments($variables), - ); + ) + ->unwrap(); $console = $process ->output() - ->reduce( - $console, - static fn(Console $console, $line) => $console->output($line), - ); + ->map(static fn($chunk) => $chunk->data()) + ->sink($console) + ->attempt(static fn(Console $console, $line) => $console->output($line)) + ->unwrap(); $successful = $process->wait()->match( static fn() => true, static fn() => false, @@ -105,7 +107,8 @@ private function run(Console $console, OperatingSystem $os): Console }, ), ) - ->wait() + ->either() + ->flatMap(static fn($process) => $process->wait()) ->match( static fn() => $console, static fn() => $console, diff --git a/tests/Agent/WatchFixturesTest.php b/tests/Agent/WatchFixturesTest.php index bb4c512..b988d35 100644 --- a/tests/Agent/WatchFixturesTest.php +++ b/tests/Agent/WatchFixturesTest.php @@ -14,17 +14,15 @@ }; use Innmind\OperatingSystem\{ OperatingSystem, - Filesystem, + Config, }; -use Innmind\FileWatch\{ - Ping, - Continuation, +use Innmind\Filesystem\{ + Adapter, + Directory, }; +use Innmind\FileWatch\Watch; use Innmind\Url\Path; -use Innmind\Immutable\{ - Maybe, - Set, -}; +use Innmind\Immutable\Set; use PHPUnit\Framework\TestCase; class WatchFixturesTest extends TestCase @@ -41,8 +39,17 @@ public function testSendMessageWhenFixturesAreModified() { $agent = new WatchFixtures; - $os = $this->createMock(OperatingSystem::class); - $filesystem = $this->createMock(Filesystem::class); + $adapter = Adapter::inMemory(); + $_ = $adapter + ->add(Directory::named('fixtures')) + ->unwrap(); + + $os = OperatingSystem::new( + Config::new() + ->mountFilesystemVia(static fn() => Attempt::result($adapter)) + ->useFileWatch(Watch::via()), // todo simulate file change + ); + $activities = Activities::new( $this->createMock(Trigger::class), new Iteration, @@ -50,29 +57,6 @@ public function testSendMessageWhenFixturesAreModified() ); $project = Path::of('/vendor/package/'); - $os - ->method('filesystem') - ->willReturn($filesystem); - $filesystem - ->expects($this->once()) - ->method('contains') - ->with(Path::of('/vendor/package/fixtures/')) - ->willReturn(true); - $filesystem - ->expects($this->once()) - ->method('watch') - ->with(Path::of('/vendor/package/fixtures/')) - ->willReturn($ping = $this->createMock(Ping::class)); - $ping - ->expects($this->once()) - ->method('__invoke') - ->with($activities, $this->callback(static function($listen) use ($activities): bool { - $listen($activities, Continuation::of($activities)); // simulate folder modification - - return true; - })) - ->willReturn(Maybe::of($activities)); - $this->assertSame($agent, $agent($os, $project, $activities)); $this->assertEquals( [ @@ -87,8 +71,7 @@ public function testDoesntWatchWhenTheFolderDoesntExist() { $agent = new WatchFixtures; - $os = $this->createMock(OperatingSystem::class); - $filesystem = $this->createMock(Filesystem::class); + $os = OperatingSystem::new(); $activities = Activities::new( $this->createMock(Trigger::class), new Iteration, @@ -96,18 +79,6 @@ public function testDoesntWatchWhenTheFolderDoesntExist() ); $project = Path::of('/vendor/package/'); - $os - ->method('filesystem') - ->willReturn($filesystem); - $filesystem - ->expects($this->once()) - ->method('contains') - ->with(Path::of('/vendor/package/fixtures/')) - ->willReturn(false); - $filesystem - ->expects($this->never()) - ->method('watch'); - $this->assertNull($agent($os, $project, $activities)); $this->assertEquals( [Activity::start], diff --git a/tests/Agent/WatchProofsTest.php b/tests/Agent/WatchProofsTest.php index 3738440..6b2ed9c 100644 --- a/tests/Agent/WatchProofsTest.php +++ b/tests/Agent/WatchProofsTest.php @@ -14,17 +14,15 @@ }; use Innmind\OperatingSystem\{ OperatingSystem, - Filesystem, + Config, }; -use Innmind\FileWatch\{ - Ping, - Continuation, +use Innmind\Filesystem\{ + Adapter, + Directory, }; +use Innmind\FileWatch\Watch; use Innmind\Url\Path; -use Innmind\Immutable\{ - Maybe, - Set, -}; +use Innmind\Immutable\Set; use PHPUnit\Framework\TestCase; class WatchProofsTest extends TestCase @@ -41,8 +39,17 @@ public function testSendMessageWhenProofsAreModified() { $agent = new WatchProofs; - $os = $this->createMock(OperatingSystem::class); - $filesystem = $this->createMock(Filesystem::class); + $adapter = Adapter::inMemory(); + $_ = $adapter + ->add(Directory::named('proofs')) + ->unwrap(); + + $os = OperatingSystem::new( + Config::new() + ->mountFilesystemVia(static fn() => Attempt::result($adapter)) + ->useFileWatch(Watch::via()), // todo simulate file change + ); + $activities = Activities::new( $this->createMock(Trigger::class), new Iteration, @@ -50,29 +57,6 @@ public function testSendMessageWhenProofsAreModified() ); $project = Path::of('/vendor/package/'); - $os - ->method('filesystem') - ->willReturn($filesystem); - $filesystem - ->expects($this->once()) - ->method('contains') - ->with(Path::of('/vendor/package/proofs/')) - ->willReturn(true); - $filesystem - ->expects($this->once()) - ->method('watch') - ->with(Path::of('/vendor/package/proofs/')) - ->willReturn($ping = $this->createMock(Ping::class)); - $ping - ->expects($this->once()) - ->method('__invoke') - ->with($activities, $this->callback(static function($listen) use ($activities): bool { - $listen($activities, Continuation::of($activities)); // simulate folder modification - - return true; - })) - ->willReturn(Maybe::just($activities)); - $this->assertSame($agent, $agent($os, $project, $activities)); $this->assertEquals( [ @@ -87,8 +71,7 @@ public function testDoesntWatchWhenTheFolderDoesntExist() { $agent = new WatchProofs; - $os = $this->createMock(OperatingSystem::class); - $filesystem = $this->createMock(Filesystem::class); + $os = OperatingSystem::new(); $activities = Activities::new( $this->createMock(Trigger::class), new Iteration, @@ -96,18 +79,6 @@ public function testDoesntWatchWhenTheFolderDoesntExist() ); $project = Path::of('/vendor/package/'); - $os - ->method('filesystem') - ->willReturn($filesystem); - $filesystem - ->expects($this->once()) - ->method('contains') - ->with(Path::of('/vendor/package/proofs/')) - ->willReturn(false); - $filesystem - ->expects($this->never()) - ->method('watch'); - $this->assertNull($agent($os, $project, $activities)); $this->assertEquals( [Activity::start], diff --git a/tests/Agent/WatchPropertiesTest.php b/tests/Agent/WatchPropertiesTest.php index adbb8f8..1d1377d 100644 --- a/tests/Agent/WatchPropertiesTest.php +++ b/tests/Agent/WatchPropertiesTest.php @@ -14,17 +14,15 @@ }; use Innmind\OperatingSystem\{ OperatingSystem, - Filesystem, + Config, }; -use Innmind\FileWatch\{ - Ping, - Continuation, +use Innmind\Filesystem\{ + Adapter, + Directory, }; +use Innmind\FileWatch\Watch; use Innmind\Url\Path; -use Innmind\Immutable\{ - Maybe, - Set, -}; +use Innmind\Immutable\Set; use PHPUnit\Framework\TestCase; class WatchPropertiesTest extends TestCase @@ -41,8 +39,17 @@ public function testSendMessageWhenSourcesAreModified() { $agent = new WatchProperties; - $os = $this->createMock(OperatingSystem::class); - $filesystem = $this->createMock(Filesystem::class); + $adapter = Adapter::inMemory(); + $_ = $adapter + ->add(Directory::named('properties')) + ->unwrap(); + + $os = OperatingSystem::new( + Config::new() + ->mountFilesystemVia(static fn() => Attempt::result($adapter)) + ->useFileWatch(Watch::via()), // todo simulate file change + ); + $activities = Activities::new( $this->createMock(Trigger::class), new Iteration, @@ -50,29 +57,6 @@ public function testSendMessageWhenSourcesAreModified() ); $project = Path::of('/vendor/package/'); - $os - ->method('filesystem') - ->willReturn($filesystem); - $filesystem - ->expects($this->once()) - ->method('contains') - ->with(Path::of('/vendor/package/properties/')) - ->willReturn(true); - $filesystem - ->expects($this->once()) - ->method('watch') - ->with(Path::of('/vendor/package/properties/')) - ->willReturn($ping = $this->createMock(Ping::class)); - $ping - ->expects($this->once()) - ->method('__invoke') - ->with($activities, $this->callback(static function($listen) use ($activities): bool { - $listen($activities, Continuation::of($activities)); // simulate folder modification - - return true; - })) - ->willReturn(Maybe::just($activities)); - $this->assertSame($agent, $agent($os, $project, $activities)); $this->assertEquals( [ @@ -87,8 +71,7 @@ public function testDoesntWatchWhenTheFolderDoesntExist() { $agent = new WatchProperties; - $os = $this->createMock(OperatingSystem::class); - $filesystem = $this->createMock(Filesystem::class); + $os = OperatingSystem::new(); $activities = Activities::new( $this->createMock(Trigger::class), new Iteration, @@ -96,18 +79,6 @@ public function testDoesntWatchWhenTheFolderDoesntExist() ); $project = Path::of('/vendor/package/'); - $os - ->method('filesystem') - ->willReturn($filesystem); - $filesystem - ->expects($this->once()) - ->method('contains') - ->with(Path::of('/vendor/package/properties/')) - ->willReturn(false); - $filesystem - ->expects($this->never()) - ->method('watch'); - $this->assertNull($agent($os, $project, $activities)); $this->assertEquals( [Activity::start], diff --git a/tests/Agent/WatchSourcesTest.php b/tests/Agent/WatchSourcesTest.php index 3b3895e..b0292ac 100644 --- a/tests/Agent/WatchSourcesTest.php +++ b/tests/Agent/WatchSourcesTest.php @@ -14,17 +14,12 @@ }; use Innmind\OperatingSystem\{ OperatingSystem, - Filesystem, -}; -use Innmind\FileWatch\{ - Ping, - Continuation, + Config, }; +use Innmind\Filesystem\Adapter; +use Innmind\FileWatch\Watch; use Innmind\Url\Path; -use Innmind\Immutable\{ - Maybe, - Set, -}; +use Innmind\Immutable\Set; use PHPUnit\Framework\TestCase; class WatchSourcesTest extends TestCase @@ -41,8 +36,12 @@ public function testSendMessageWhenSourcesAreModified() { $agent = new WatchSources; - $os = $this->createMock(OperatingSystem::class); - $filesystem = $this->createMock(Filesystem::class); + $os = OperatingSystem::new( + Config::new() + ->mountFilesystemVia(static fn() => Attempt::result(Adapter::inMemory())) + ->useFileWatch(Watch::via()), // todo simulate file change + ); + $activities = Activities::new( $this->createMock(Trigger::class), new Iteration, @@ -50,24 +49,6 @@ public function testSendMessageWhenSourcesAreModified() ); $project = Path::of('/vendor/package/'); - $os - ->method('filesystem') - ->willReturn($filesystem); - $filesystem - ->expects($this->once()) - ->method('watch') - ->with(Path::of('/vendor/package/src/')) - ->willReturn($ping = $this->createMock(Ping::class)); - $ping - ->expects($this->once()) - ->method('__invoke') - ->with($activities, $this->callback(static function($listen) use ($activities): bool { - $listen($activities, Continuation::of($activities)); // simulate folder modification - - return true; - })) - ->willReturn(Maybe::just($activities)); - $this->assertSame($agent, $agent($os, $project, $activities)); $this->assertEquals( [ diff --git a/tests/Agent/WatchTestsTest.php b/tests/Agent/WatchTestsTest.php index 061d08b..ffbf693 100644 --- a/tests/Agent/WatchTestsTest.php +++ b/tests/Agent/WatchTestsTest.php @@ -14,17 +14,12 @@ }; use Innmind\OperatingSystem\{ OperatingSystem, - Filesystem, -}; -use Innmind\FileWatch\{ - Ping, - Continuation, + Config, }; +use Innmind\Filesystem\Adapter; +use Innmind\FileWatch\Watch; use Innmind\Url\Path; -use Innmind\Immutable\{ - Maybe, - Set, -}; +use Innmind\Immutable\Set; use PHPUnit\Framework\TestCase; class WatchTestsTest extends TestCase @@ -41,8 +36,12 @@ public function testSendMessageWhenSourcesAreModified() { $agent = new WatchTests; - $os = $this->createMock(OperatingSystem::class); - $filesystem = $this->createMock(Filesystem::class); + $os = OperatingSystem::new( + Config::new() + ->mountFilesystemVia(static fn() => Attempt::result(Adapter::inMemory())) + ->useFileWatch(Watch::via()), // todo simulate file change + ); + $activities = Activities::new( $this->createMock(Trigger::class), new Iteration, @@ -50,29 +49,6 @@ public function testSendMessageWhenSourcesAreModified() ); $project = Path::of('/vendor/package/'); - $os - ->method('filesystem') - ->willReturn($filesystem); - $filesystem - ->expects($this->once()) - ->method('contains') - ->with(Path::of('/vendor/package/tests/')) - ->willReturn(true); - $filesystem - ->expects($this->once()) - ->method('watch') - ->with(Path::of('/vendor/package/tests/')) - ->willReturn($ping = $this->createMock(Ping::class)); - $ping - ->expects($this->once()) - ->method('__invoke') - ->with($activities, $this->callback(static function($listen) use ($activities): bool { - $listen($activities, Continuation::of($activities)); // simulate folder modification - - return true; - })) - ->willReturn(Maybe::just($activities)); - $this->assertSame($agent, $agent($os, $project, $activities)); $this->assertEquals( [ @@ -87,8 +63,7 @@ public function testDoesntWatchWhenTheFolderDoesntExist() { $agent = new WatchTests; - $os = $this->createMock(OperatingSystem::class); - $filesystem = $this->createMock(Filesystem::class); + $os = OperatingSystem::new(); $activities = Activities::new( $this->createMock(Trigger::class), new Iteration, @@ -96,18 +71,6 @@ public function testDoesntWatchWhenTheFolderDoesntExist() ); $project = Path::of('/vendor/package/'); - $os - ->method('filesystem') - ->willReturn($filesystem); - $filesystem - ->expects($this->once()) - ->method('contains') - ->with(Path::of('/vendor/package/tests/')) - ->willReturn(false); - $filesystem - ->expects($this->never()) - ->method('watch'); - $this->assertNull($agent($os, $project, $activities)); $this->assertEquals( [Activity::start], diff --git a/tests/BootstrapTest.php b/tests/BootstrapTest.php index ab0df9f..9ae4756 100644 --- a/tests/BootstrapTest.php +++ b/tests/BootstrapTest.php @@ -12,7 +12,7 @@ class BootstrapTest extends TestCase { public function testInvokation() { - $os = $this->createMock(OperatingSystem::class); + $os = OperatingSystem::new(); $this->assertInstanceOf(Commands::class, bootstrap($os)); } diff --git a/tests/Command/WorkTest.php b/tests/Command/WorkTest.php index dffc4c9..3c38c7f 100644 --- a/tests/Command/WorkTest.php +++ b/tests/Command/WorkTest.php @@ -21,7 +21,7 @@ public function testInterface() Command::class, new Work( new Monitor( - $this->createMock(OperatingSystem::class), + OperatingSystem::new(), new Iteration, $this->createMock(Trigger::class), ), @@ -33,7 +33,7 @@ public function testUsage() { $this->assertSame( <<createMock(OperatingSystem::class), + OperatingSystem::new(), new Iteration, $this->createMock(Trigger::class), ), - ))->usage(), + ))->usage()->toString(), ); } } diff --git a/tests/IterationTest.php b/tests/IterationTest.php index ce406b2..f030bec 100644 --- a/tests/IterationTest.php +++ b/tests/IterationTest.php @@ -19,7 +19,7 @@ public function testEndingAnIterationWithoutAStartWillClearTheTerminal() { $iteration = new Iteration; $console = Console::of( - Environment\InMemory::of( + Environment::inMemory( [], true, [], @@ -33,7 +33,11 @@ public function testEndingAnIterationWithoutAStartWillClearTheTerminal() $console = $iteration->end($console); $this->assertSame( ["\033[2J\033[H"], - $console->environment()->outputs(), + $console + ->environment() + ->outputted() + ->map(static fn($chunk) => $chunk[0]->toString()) + ->toList(), ); } @@ -41,7 +45,7 @@ public function testNormalIterationWithoutAFailureWillClearTheTerminal() { $iteration = new Iteration; $console = Console::of( - Environment\InMemory::of( + Environment::inMemory( [], true, [], @@ -56,7 +60,11 @@ public function testNormalIterationWithoutAFailureWillClearTheTerminal() $console = $iteration->end($console); $this->assertSame( ["\033[2J\033[H"], - $console->environment()->outputs(), + $console + ->environment() + ->outputted() + ->map(static fn($chunk) => $chunk[0]->toString()) + ->toList(), ); } @@ -64,7 +72,7 @@ public function testNormalIterationWithAFailureWillNotClearTheTerminal() { $iteration = new Iteration; $console = Console::of( - Environment\InMemory::of( + Environment::inMemory( [], true, [], @@ -78,14 +86,21 @@ public function testNormalIterationWithAFailureWillNotClearTheTerminal() $iteration->start(); $iteration->failing(); $console = $iteration->end($console); - $this->assertSame([], $console->environment()->outputs()); + $this->assertSame( + [], + $console + ->environment() + ->outputted() + ->map(static fn($chunk) => $chunk[0]->toString()) + ->toList(), + ); } public function testNormalIterationWithoutAFailureWillNotClearTheTerminalWhenExplicitlyAskToKeepOutput() { $iteration = new Iteration; $console = Console::of( - Environment\InMemory::of( + Environment::inMemory( [], true, ['--keep-output'], @@ -98,14 +113,21 @@ public function testNormalIterationWithoutAFailureWillNotClearTheTerminalWhenExp $iteration->start(); $console = $iteration->end($console); - $this->assertSame([], $console->environment()->outputs()); + $this->assertSame( + [], + $console + ->environment() + ->outputted() + ->map(static fn($chunk) => $chunk[0]->toString()) + ->toList(), + ); } public function testNormalIterationWithAFailureWillNotClearTheTerminalWhenExplicitlyAskToKeepOutput() { $iteration = new Iteration; $console = Console::of( - Environment\InMemory::of( + Environment::inMemory( [], true, ['--keep-output'], @@ -119,14 +141,21 @@ public function testNormalIterationWithAFailureWillNotClearTheTerminalWhenExplic $iteration->start(); $iteration->failing(); $console = $iteration->end($console); - $this->assertSame([], $console->environment()->outputs()); + $this->assertSame( + [], + $console + ->environment() + ->outputted() + ->map(static fn($chunk) => $chunk[0]->toString()) + ->toList(), + ); } public function testClearTheTerminalEvenWhenPreviousIterationFailed() { $iteration = new Iteration; $console = Console::of( - Environment\InMemory::of( + Environment::inMemory( [], true, [], @@ -144,7 +173,11 @@ public function testClearTheTerminalEvenWhenPreviousIterationFailed() $console = $iteration->end($console); $this->assertSame( ["\033[2J\033[H"], - $console->environment()->outputs(), + $console + ->environment() + ->outputted() + ->map(static fn($chunk) => $chunk[0]->toString()) + ->toList(), ); } } diff --git a/tests/Trigger/AllTest.php b/tests/Trigger/AllTest.php index 487932b..330c661 100644 --- a/tests/Trigger/AllTest.php +++ b/tests/Trigger/AllTest.php @@ -35,11 +35,17 @@ public function testTriggerAllSubTriggers() $triggers = Set::of(); $activity = Activity::start; $console = Console::of( - $this->createMock(Environment::class), + Environment::inMemory( + [], + true, + [], + [], + '/somewhere', + ), new Arguments, new Options, ); - $os = $this->createMock(OperatingSystem::class); + $os = OperatingSystem::new(); $trigger1 ->expects($this->once()) ->method('__invoke') diff --git a/tests/Trigger/BlackBoxTest.php b/tests/Trigger/BlackBoxTest.php index e575b9a..9eacd04 100644 --- a/tests/Trigger/BlackBoxTest.php +++ b/tests/Trigger/BlackBoxTest.php @@ -12,14 +12,12 @@ }; use Innmind\OperatingSystem\{ OperatingSystem, - Filesystem, + Config, }; use Innmind\Server\Control\{ Server, - Server\Processes, - Server\Process, + Server\Process\Builder, Server\Process\Output, - Server\Process\ExitCode, }; use Innmind\CLI\{ Environment, @@ -33,12 +31,9 @@ File\Content, }; use Innmind\Immutable\{ - Sequence, - Str, - Either, - SideEffect, Map, Set as ISet, + Attempt, }; use PHPUnit\Framework\TestCase; use Innmind\BlackBox\{ @@ -62,15 +57,15 @@ public function testDoNothingWhenNotOfExpectedType() { $trigger = new BlackBox(new Iteration); - $os = $this->createMock(OperatingSystem::class); - $os - ->expects($this->never()) - ->method('filesystem'); - $os - ->expects($this->never()) - ->method('control'); + $os = OperatingSystem::new(); $console = Console::of( - $this->createMock(Environment::class), + Environment::inMemory( + [], + true, + [], + [], + '/somewhere', + ), new Arguments, new Options, ); @@ -90,15 +85,9 @@ public function testDoNothingWhenTriggerNotEnabled() ->then(function($type) { $trigger = new BlackBox(new Iteration); - $os = $this->createMock(OperatingSystem::class); - $os - ->expects($this->never()) - ->method('filesystem'); - $os - ->expects($this->never()) - ->method('control'); + $os = OperatingSystem::new(); $console = Console::of( - Environment\InMemory::of( + Environment::inMemory( [], true, [], @@ -117,11 +106,11 @@ public function testDoNothingWhenTriggerNotEnabled() ); $this->assertSame( [], - $console->environment()->outputs(), - ); - $this->assertSame( - [], - $console->environment()->errors(), + $console + ->environment() + ->outputted() + ->map(static fn($chunk) => $chunk[0]->toString()) + ->toList(), ); }); } @@ -139,79 +128,53 @@ public function testTriggerTestsSuiteWhenActivity() $trigger = new BlackBox( $iteration = new Iteration, ); - - $os = $this->createMock(OperatingSystem::class); - $filesystem = $this->createMock(Filesystem::class); - $server = $this->createMock(Server::class); - $processes = $this->createMock(Processes::class); - $adapter = Adapter\InMemory::new(); - $adapter->add(File::named( + $adapter = Adapter::inMemory(); + $_ = $adapter->add(File::named( 'blackbox.php', Content::none(), - )); - - $os - ->method('filesystem') - ->willReturn($filesystem); - $filesystem - ->expects($this->once()) - ->method('mount') - ->willReturn($adapter); - $tests = $this->createMock(Process::class); - $say = $this->createMock(Process::class); - $os - ->method('control') - ->willReturn($server); - $server - ->method('processes') - ->willReturn($processes); - $processes - ->expects($matcher = $this->exactly(2)) - ->method('execute') - ->willReturnCallback(function($command) use ($matcher, $tests, $say) { - match ($matcher->numberOfInvocations()) { - 1 => $this->assertSame( - "php 'blackbox.php'", - $command->toString(), - ), - 2 => $this->assertSame( - "say 'BlackBox : ok'", - $command->toString(), - ), - }; - - if ($matcher->numberOfInvocations() === 1) { - $this->assertSame('/somewhere/', $command->workingDirectory()->match( - static fn($path) => $path->toString(), - static fn() => null, - )); - } + ))->unwrap(); + + $count = 0; + $os = OperatingSystem::new( + Config::new() + ->mountFilesystemVia(static fn() => Attempt::result($adapter)) + ->useServerControl(Server::via( + function($command) use (&$count) { + $this->assertSame( + match ($count) { + 0 => "php 'blackbox.php'", + 1 => "say 'BlackBox : ok'", + }, + $command->toString(), + ); + + if ($count === 0) { + $this->assertSame('/somewhere/', $command->workingDirectory()->match( + static fn($path) => $path->toString(), + static fn() => null, + )); + } + + $builder = Builder::foreground(2); + // we say here that tests are successful even though we have an + // error in the output in order to verify the terminal is cleared + // on success + $builder = match ($count) { + 0 => $builder->success([ + ['some output', 'output'], + ['some error', 'error'], + ]), + 1 => $builder, + }; + ++$count; + + return Attempt::result($builder->build()); + }, + )), + ); - return match ($matcher->numberOfInvocations()) { - 1 => $tests, - 2 => $say, - }; - }); - $tests - ->expects($this->once()) - ->method('output') - ->willReturn(new Output\Output(Sequence::of( - [Str::of('some output'), Output\Type::output], - [Str::of('some error'), Output\Type::error], - ))); - // we say here that tests are successful even though we have an - // error in the output in order to verify the terminal is cleared - // on success - $tests - ->expects($this->once()) - ->method('wait') - ->willReturn(Either::right(new SideEffect)); - $say - ->expects($this->once()) - ->method('wait') - ->willReturn(Either::right(new SideEffect)); $console = Console::of( - Environment\InMemory::of( + Environment::inMemory( [], true, [], @@ -232,11 +195,11 @@ public function testTriggerTestsSuiteWhenActivity() $console = $iteration->end($console); $this->assertSame( ['some output', 'some error', "\033[2J\033[H"], - $console->environment()->outputs(), - ); - $this->assertSame( - [], - $console->environment()->errors(), + $console + ->environment() + ->outputted() + ->map(static fn($chunk) => $chunk[0]->toString()) + ->toList(), ); }); } @@ -255,22 +218,14 @@ public function testDoesntTriggerWhenNoBlackBoxFile() $iteration = new Iteration, ); - $os = $this->createMock(OperatingSystem::class); - $filesystem = $this->createMock(Filesystem::class); - $adapter = Adapter\InMemory::new(); - - $os - ->method('filesystem') - ->willReturn($filesystem); - $filesystem - ->expects($this->once()) - ->method('mount') - ->willReturn($adapter); - $os - ->expects($this->never()) - ->method('control'); + $os = OperatingSystem::new( + Config::new()->mountFilesystemVia( + static fn() => Attempt::result(Adapter::inMemory()), + ), + ); + $console = Console::of( - Environment\InMemory::of( + Environment::inMemory( [], true, [], @@ -291,11 +246,11 @@ public function testDoesntTriggerWhenNoBlackBoxFile() $console = $iteration->end($console); $this->assertSame( ["\033[2J\033[H"], - $console->environment()->outputs(), - ); - $this->assertSame( - [], - $console->environment()->errors(), + $console + ->environment() + ->outputted() + ->map(static fn($chunk) => $chunk[0]->toString()) + ->toList(), ); }); } @@ -305,73 +260,44 @@ public function testDoesntClearTerminalOnSuccessfullTestWhenSpecifiedOptionProvi $trigger = new BlackBox( $iteration = new Iteration, ); - - $os = $this->createMock(OperatingSystem::class); - $filesystem = $this->createMock(Filesystem::class); - $server = $this->createMock(Server::class); - $processes = $this->createMock(Processes::class); - $adapter = Adapter\InMemory::new(); - $adapter->add(File::named( + $adapter = Adapter::inMemory(); + $_ = $adapter->add(File::named( 'blackbox.php', Content::none(), - )); + ))->unwrap(); + + $count = 0; + $os = OperatingSystem::new( + Config::new() + ->mountFilesystemVia(static fn() => Attempt::result($adapter)) + ->useServerControl(Server::via( + function($command) use (&$count) { + $this->assertSame( + match ($count) { + 0 => "php 'blackbox.php'", + 1 => "say 'BlackBox : ok'", + }, + $command->toString(), + ); + + if ($count === 0) { + $this->assertSame('/somewhere/', $command->workingDirectory()->match( + static fn($path) => $path->toString(), + static fn() => null, + )); + } + + ++$count; + + return Attempt::result( + Builder::foreground(2)->build(), + ); + }, + )), + ); - $os - ->method('filesystem') - ->willReturn($filesystem); - $filesystem - ->expects($this->once()) - ->method('mount') - ->willReturn($adapter); - $tests = $this->createMock(Process::class); - $say = $this->createMock(Process::class); - $os - ->method('control') - ->willReturn($server); - $server - ->method('processes') - ->willReturn($processes); - $processes - ->expects($matcher = $this->exactly(2)) - ->method('execute') - ->willReturnCallback(function($command) use ($matcher, $tests, $say) { - match ($matcher->numberOfInvocations()) { - 1 => $this->assertSame( - "php 'blackbox.php'", - $command->toString(), - ), - 2 => $this->assertSame( - "say 'BlackBox : ok'", - $command->toString(), - ), - }; - - if ($matcher->numberOfInvocations() === 1) { - $this->assertSame('/somewhere/', $command->workingDirectory()->match( - static fn($path) => $path->toString(), - static fn() => null, - )); - } - - return match ($matcher->numberOfInvocations()) { - 1 => $tests, - 2 => $say, - }; - }); - $tests - ->expects($this->once()) - ->method('wait') - ->willReturn(Either::right(new SideEffect)); - $tests - ->expects($this->once()) - ->method('output') - ->willReturn(new Output\Output(Sequence::of())); - $say - ->expects($this->once()) - ->method('wait') - ->willReturn(Either::right(new SideEffect)); $console = Console::of( - Environment\InMemory::of( + Environment::inMemory( [], true, ['--keep-output'], @@ -390,7 +316,14 @@ public function testDoesntClearTerminalOnSuccessfullTestWhenSpecifiedOptionProvi ISet::of(Triggers::proofs), ); $console = $iteration->end($console); - $this->assertSame([], $console->environment()->outputs()); + $this->assertSame( + [], + $console + ->environment() + ->outputted() + ->map(static fn($chunk) => $chunk[0]->toString()) + ->toList(), + ); } public function testSaidMessageIsChangedWhenTestsAreFailing() @@ -398,73 +331,47 @@ public function testSaidMessageIsChangedWhenTestsAreFailing() $trigger = new BlackBox( $iteration = new Iteration, ); - - $os = $this->createMock(OperatingSystem::class); - $filesystem = $this->createMock(Filesystem::class); - $server = $this->createMock(Server::class); - $processes = $this->createMock(Processes::class); - $adapter = Adapter\InMemory::new(); - $adapter->add(File::named( + $adapter = Adapter::inMemory(); + $_ = $adapter->add(File::named( 'blackbox.php', Content::none(), - )); + ))->unwrap(); + + $count = 0; + $os = OperatingSystem::new( + Config::new() + ->mountFilesystemVia(static fn() => Attempt::result($adapter)) + ->useServerControl(Server::via( + function($command) use (&$count) { + $this->assertSame( + match ($count) { + 0 => "php 'blackbox.php'", + 1 => "say 'BlackBox : failing'", + }, + $command->toString(), + ); + + if ($count === 0) { + $this->assertSame('/somewhere/', $command->workingDirectory()->match( + static fn($path) => $path->toString(), + static fn() => null, + )); + } + + $builder = Builder::foreground(2); + $builder = match ($count) { + 0 => $builder->failed(), + 1 => $builder, + }; + ++$count; + + return Attempt::result($builder->build()); + }, + )), + ); - $os - ->method('filesystem') - ->willReturn($filesystem); - $filesystem - ->expects($this->once()) - ->method('mount') - ->willReturn($adapter); - $tests = $this->createMock(Process::class); - $say = $this->createMock(Process::class); - $os - ->method('control') - ->willReturn($server); - $server - ->method('processes') - ->willReturn($processes); - $processes - ->expects($matcher = $this->exactly(2)) - ->method('execute') - ->willReturnCallback(function($command) use ($matcher, $tests, $say) { - match ($matcher->numberOfInvocations()) { - 1 => $this->assertSame( - "php 'blackbox.php'", - $command->toString(), - ), - 2 => $this->assertSame( - "say 'BlackBox : failing'", - $command->toString(), - ), - }; - - if ($matcher->numberOfInvocations() === 1) { - $this->assertSame('/somewhere/', $command->workingDirectory()->match( - static fn($path) => $path->toString(), - static fn() => null, - )); - } - - return match ($matcher->numberOfInvocations()) { - 1 => $tests, - 2 => $say, - }; - }); - $tests - ->expects($this->once()) - ->method('output') - ->willReturn(new Output\Output(Sequence::of())); - $tests - ->expects($this->once()) - ->method('wait') - ->willReturn(Either::left(new ExitCode(1))); - $say - ->expects($this->once()) - ->method('wait') - ->willReturn(Either::right(new SideEffect)); $console = Console::of( - Environment\InMemory::of( + Environment::inMemory( [], true, [], @@ -483,7 +390,14 @@ public function testSaidMessageIsChangedWhenTestsAreFailing() ISet::of(Triggers::proofs), ); $console = $iteration->end($console); - $this->assertSame([], $console->environment()->outputs()); + $this->assertSame( + [], + $console + ->environment() + ->outputted() + ->map(static fn($chunk) => $chunk[0]->toString()) + ->toList(), + ); } public function testNoMessageIsSpokenWhenUsingTheSilentOption() @@ -491,51 +405,40 @@ public function testNoMessageIsSpokenWhenUsingTheSilentOption() $trigger = new BlackBox( $iteration = new Iteration, ); - - $os = $this->createMock(OperatingSystem::class); - $filesystem = $this->createMock(Filesystem::class); - $server = $this->createMock(Server::class); - $processes = $this->createMock(Processes::class); - $adapter = Adapter\InMemory::new(); - $adapter->add(File::named( + $adapter = Adapter::inMemory(); + $_ = $adapter->add(File::named( 'blackbox.php', Content::none(), - )); + ))->unwrap(); + + $count = 0; + $os = OperatingSystem::new( + Config::new() + ->mountFilesystemVia(static fn() => Attempt::result($adapter)) + ->useServerControl(Server::via( + function($command) use (&$count) { + $this->assertSame( + match ($count) { + 0 => "php 'blackbox.php'", + }, + $command->toString(), + ); + $this->assertSame('/somewhere/', $command->workingDirectory()->match( + static fn($path) => $path->toString(), + static fn() => null, + )); + + ++$count; + + return Attempt::result( + Builder::foreground(2)->build(), + ); + }, + )), + ); - $os - ->method('filesystem') - ->willReturn($filesystem); - $filesystem - ->expects($this->once()) - ->method('mount') - ->willReturn($adapter); - $os - ->method('control') - ->willReturn($server); - $server - ->method('processes') - ->willReturn($processes); - $processes - ->expects($this->once()) - ->method('execute') - ->with($this->callback(static function($command): bool { - return $command->toString() === "php 'blackbox.php'" && - '/somewhere/' === $command->workingDirectory()->match( - static fn($path) => $path->toString(), - static fn() => null, - ); - })) - ->willReturn($process = $this->createMock(Process::class)); - $process - ->expects($this->once()) - ->method('wait') - ->willReturn(Either::right(new SideEffect)); - $process - ->expects($this->once()) - ->method('output') - ->willReturn(new Output\Output(Sequence::of())); $console = Console::of( - Environment\InMemory::of( + Environment::inMemory( [], true, ['--silent'], @@ -554,7 +457,13 @@ public function testNoMessageIsSpokenWhenUsingTheSilentOption() ISet::of(Triggers::proofs), ); $console = $iteration->end($console); - $this->assertSame(["\033[2J\033[H"], $console->environment()->outputs()); - $this->assertSame([], $console->environment()->errors()); + $this->assertSame( + ["\033[2J\033[H"], + $console + ->environment() + ->outputted() + ->map(static fn($chunk) => $chunk[0]->toString()) + ->toList(), + ); } } diff --git a/tests/Trigger/CodingStandardTest.php b/tests/Trigger/CodingStandardTest.php index 018b47e..f807339 100644 --- a/tests/Trigger/CodingStandardTest.php +++ b/tests/Trigger/CodingStandardTest.php @@ -12,10 +12,7 @@ }; use Innmind\Server\Control\{ Server, - Server\Processes, - Server\Process, - Server\Process\Output, - Server\Process\ExitCode, + Server\Process\Builder, }; use Innmind\CLI\{ Environment, @@ -23,10 +20,9 @@ Command\Arguments, Command\Options, }; -use Innmind\Url\Path; use Innmind\OperatingSystem\{ OperatingSystem, - Filesystem, + Config, }; use Innmind\Filesystem\{ Adapter, @@ -34,12 +30,9 @@ File\Content, }; use Innmind\Immutable\{ - Sequence, - Str, - Either, - SideEffect, Map, Set, + Attempt, }; use PHPUnit\Framework\TestCase; use Innmind\BlackBox\{ @@ -65,15 +58,15 @@ public function testDoNothingWhenNotOfExpectedType() { $trigger = new CodingStandard(new Iteration); - $os = $this->createMock(OperatingSystem::class); - $os - ->expects($this->never()) - ->method('filesystem'); - $os - ->expects($this->never()) - ->method('control'); + $os = OperatingSystem::new(); $console = Console::of( - $this->createMock(Environment::class), + Environment::inMemory( + [], + true, + [], + [], + '/somewhere', + ), new Arguments, new Options, ); @@ -90,21 +83,14 @@ public function testDoNothingWhenToolNotInstalled() { $trigger = new CodingStandard(new Iteration); - $os = $this->createMock(OperatingSystem::class); - $filesystem = $this->createMock(Filesystem::class); - - $os - ->method('filesystem') - ->willReturn($filesystem); - $filesystem - ->expects($this->once()) - ->method('mount') - ->willReturn(Adapter\InMemory::new()); - $os - ->expects($this->never()) - ->method('control'); + $os = OperatingSystem::new( + Config::new()->mountFilesystemVia( + static fn() => Attempt::result(Adapter::inMemory()), + ), + ); + $console = Console::of( - Environment\InMemory::of( + Environment::inMemory( [], true, [], @@ -127,15 +113,9 @@ public function testDoNothingWhenTriggerNotEnabled() { $trigger = new CodingStandard(new Iteration); - $os = $this->createMock(OperatingSystem::class); - $os - ->expects($this->never()) - ->method('filesystem'); - $os - ->expects($this->never()) - ->method('control'); + $os = OperatingSystem::new(); $console = Console::of( - Environment\InMemory::of( + Environment::inMemory( [], true, [], @@ -154,11 +134,11 @@ public function testDoNothingWhenTriggerNotEnabled() ); $this->assertSame( [], - $console->environment()->outputs(), - ); - $this->assertSame( - [], - $console->environment()->errors(), + $console + ->environment() + ->outputted() + ->map(static fn($chunk) => $chunk[0]->toString()) + ->toList(), ); } @@ -176,77 +156,50 @@ public function testTriggerTestsSuiteWhenSourcesModified() $trigger = new CodingStandard( $iteration = new Iteration, ); - - $os = $this->createMock(OperatingSystem::class); - $server = $this->createMock(Server::class); - $processes = $this->createMock(Processes::class); - $filesystem = $this->createMock(Filesystem::class); - $adapter = Adapter\InMemory::new(); - $adapter->add(File::named( + $adapter = Adapter::inMemory(); + $_ = $adapter->add(File::named( '.php_cs.dist', Content::none(), - )); - - $os - ->method('filesystem') - ->willReturn($filesystem); - $filesystem - ->expects($this->once()) - ->method('mount') - ->with(Path::of('/somewhere/')) - ->willReturn($adapter); - $cs = $this->createMock(Process::class); - $say = $this->createMock(Process::class); - $os - ->method('control') - ->willReturn($server); - $server - ->method('processes') - ->willReturn($processes); - $processes - ->expects($matcher = $this->exactly(2)) - ->method('execute') - ->willReturnCallback(function($command) use ($matcher, $cs, $say) { - match ($matcher->numberOfInvocations()) { - 1 => $this->assertSame( - "vendor/bin/php-cs-fixer 'fix' '--diff' '--dry-run' '--diff-format' 'udiff'", - $command->toString(), - ), - 2 => $this->assertSame( - "say 'Coding Standard : right'", - $command->toString(), - ), - }; - - if ($matcher->numberOfInvocations() === 1) { - $this->assertSame('/somewhere/', $command->workingDirectory()->match( - static fn($path) => $path->toString(), - static fn() => null, - )); - } + ))->unwrap(); + + $count = 0; + $os = OperatingSystem::new( + Config::new() + ->mountFilesystemVia(static fn() => Attempt::result($adapter)) + ->useServerControl(Server::via( + function($command) use (&$count) { + $this->assertSame( + match ($count) { + 0 => "vendor/bin/php-cs-fixer 'fix' '--diff' '--dry-run' '--diff-format' 'udiff'", + 1 => "say 'Coding Standard : right'", + }, + $command->toString(), + ); + + if ($count === 0) { + $this->assertSame('/somewhere/', $command->workingDirectory()->match( + static fn($path) => $path->toString(), + static fn() => null, + )); + } + + $builder = Builder::foreground(2); + $builder = match ($count) { + 0 => $builder->success([ + ['some output', 'output'], + ['some error', 'error'], + ]), + 1 => $builder, + }; + ++$count; + + return Attempt::result($builder->build()); + }, + )), + ); - return match ($matcher->numberOfInvocations()) { - 1 => $cs, - 2 => $say, - }; - }); - $cs - ->expects($this->once()) - ->method('output') - ->willReturn(new Output\Output(Sequence::of( - [Str::of('some output'), Output\Type::output], - [Str::of('some error'), Output\Type::error], - ))); - $cs - ->expects($this->once()) - ->method('wait') - ->willReturn(Either::right(new SideEffect)); - $say - ->expects($this->once()) - ->method('wait') - ->willReturn(Either::right(new SideEffect)); $console = Console::of( - Environment\InMemory::of( + Environment::inMemory( [], true, [], @@ -267,11 +220,11 @@ public function testTriggerTestsSuiteWhenSourcesModified() $console = $iteration->end($console); $this->assertSame( ['some output', 'some error', "\033[2J\033[H"], - $console->environment()->outputs(), - ); - $this->assertSame( - [], - $console->environment()->errors(), + $console + ->environment() + ->outputted() + ->map(static fn($chunk) => $chunk[0]->toString()) + ->toList(), ); }); } @@ -281,74 +234,44 @@ public function testDoesnClearTerminalOnSuccessfullTestWhenSpecifiedOptionProvid $trigger = new CodingStandard( $iteration = new Iteration, ); - - $os = $this->createMock(OperatingSystem::class); - $server = $this->createMock(Server::class); - $processes = $this->createMock(Processes::class); - $filesystem = $this->createMock(Filesystem::class); - $adapter = Adapter\InMemory::new(); - $adapter->add(File::named( + $adapter = Adapter::inMemory(); + $_ = $adapter->add(File::named( '.php_cs.dist', Content::none(), - )); + ))->unwrap(); + + $count = 0; + $os = OperatingSystem::new( + Config::new() + ->mountFilesystemVia(static fn() => Attempt::result($adapter)) + ->useServerControl(Server::via( + function($command) use (&$count) { + $this->assertSame( + match ($count) { + 0 => "vendor/bin/php-cs-fixer 'fix' '--diff' '--dry-run' '--diff-format' 'udiff'", + 1 => "say 'Coding Standard : right'", + }, + $command->toString(), + ); + + if ($count === 0) { + $this->assertSame('/somewhere/', $command->workingDirectory()->match( + static fn($path) => $path->toString(), + static fn() => null, + )); + } + + ++$count; + + return Attempt::result( + Builder::foreground(2)->build(), + ); + }, + )), + ); - $os - ->method('filesystem') - ->willReturn($filesystem); - $filesystem - ->expects($this->once()) - ->method('mount') - ->with(Path::of('/somewhere/')) - ->willReturn($adapter); - $cs = $this->createMock(Process::class); - $say = $this->createMock(Process::class); - $os - ->method('control') - ->willReturn($server); - $server - ->method('processes') - ->willReturn($processes); - $processes - ->expects($matcher = $this->exactly(2)) - ->method('execute') - ->willReturnCallback(function($command) use ($matcher, $cs, $say) { - match ($matcher->numberOfInvocations()) { - 1 => $this->assertSame( - "vendor/bin/php-cs-fixer 'fix' '--diff' '--dry-run' '--diff-format' 'udiff'", - $command->toString(), - ), - 2 => $this->assertSame( - "say 'Coding Standard : right'", - $command->toString(), - ), - }; - - if ($matcher->numberOfInvocations() === 1) { - $this->assertSame('/somewhere/', $command->workingDirectory()->match( - static fn($path) => $path->toString(), - static fn() => null, - )); - } - - return match ($matcher->numberOfInvocations()) { - 1 => $cs, - 2 => $say, - }; - }); - $cs - ->expects($this->once()) - ->method('output') - ->willReturn(new Output\Output(Sequence::of())); - $cs - ->expects($this->once()) - ->method('wait') - ->willReturn(Either::right(new SideEffect)); - $say - ->expects($this->once()) - ->method('wait') - ->willReturn(Either::right(new SideEffect)); $console = Console::of( - Environment\InMemory::of( + Environment::inMemory( [], true, ['--keep-output'], @@ -367,8 +290,14 @@ public function testDoesnClearTerminalOnSuccessfullTestWhenSpecifiedOptionProvid Set::of(Triggers::codingStandard), ); $console = $iteration->end($console); - $this->assertSame([], $console->environment()->outputs()); - $this->assertSame([], $console->environment()->errors()); + $this->assertSame( + [], + $console + ->environment() + ->outputted() + ->map(static fn($chunk) => $chunk[0]->toString()) + ->toList(), + ); } public function testTriggerForPHPCSFixer3() @@ -376,77 +305,50 @@ public function testTriggerForPHPCSFixer3() $trigger = new CodingStandard( $iteration = new Iteration, ); - - $os = $this->createMock(OperatingSystem::class); - $server = $this->createMock(Server::class); - $processes = $this->createMock(Processes::class); - $filesystem = $this->createMock(Filesystem::class); - $adapter = Adapter\InMemory::new(); - $adapter->add(File::named( + $adapter = Adapter::inMemory(); + $_ = $adapter->add(File::named( '.php-cs-fixer.dist.php', Content::none(), - )); + ))->unwrap(); + + $count = 0; + $os = OperatingSystem::new( + Config::new() + ->mountFilesystemVia(static fn() => Attempt::result($adapter)) + ->useServerControl(Server::via( + function($command) use (&$count) { + $this->assertSame( + match ($count) { + 0 => "vendor/bin/php-cs-fixer 'fix' '--diff' '--dry-run'", + 1 => "say 'Coding Standard : right'", + }, + $command->toString(), + ); + + if ($count === 0) { + $this->assertSame('/somewhere/', $command->workingDirectory()->match( + static fn($path) => $path->toString(), + static fn() => null, + )); + } + + $builder = Builder::foreground(2); + $builder = match ($count) { + 0 => $builder->success([ + ['some output', 'output'], + ['some error', 'error'], + ]), + 1 => $builder, + }; + ++$count; + + return Attempt::result($builder->build()); + }, + )), + ); - $os - ->method('filesystem') - ->willReturn($filesystem); - $filesystem - ->expects($this->once()) - ->method('mount') - ->with(Path::of('/somewhere/')) - ->willReturn($adapter); - $cs = $this->createMock(Process::class); - $say = $this->createMock(Process::class); - $os - ->method('control') - ->willReturn($server); - $server - ->method('processes') - ->willReturn($processes); - $processes - ->expects($matcher = $this->exactly(2)) - ->method('execute') - ->willReturnCallback(function($command) use ($matcher, $cs, $say) { - match ($matcher->numberOfInvocations()) { - 1 => $this->assertSame( - "vendor/bin/php-cs-fixer 'fix' '--diff' '--dry-run'", - $command->toString(), - ), - 2 => $this->assertSame( - "say 'Coding Standard : right'", - $command->toString(), - ), - }; - - if ($matcher->numberOfInvocations() === 1) { - $this->assertSame('/somewhere/', $command->workingDirectory()->match( - static fn($path) => $path->toString(), - static fn() => null, - )); - } - - return match ($matcher->numberOfInvocations()) { - 1 => $cs, - 2 => $say, - }; - }); - $cs - ->expects($this->once()) - ->method('output') - ->willReturn(new Output\Output(Sequence::of( - [Str::of('some output'), Output\Type::output], - [Str::of('some error'), Output\Type::error], - ))); - $cs - ->expects($this->once()) - ->method('wait') - ->willReturn(Either::right(new SideEffect)); - $say - ->expects($this->once()) - ->method('wait') - ->willReturn(Either::right(new SideEffect)); $console = Console::of( - Environment\InMemory::of( + Environment::inMemory( [], true, [], @@ -467,11 +369,11 @@ public function testTriggerForPHPCSFixer3() $console = $iteration->end($console); $this->assertSame( ['some output', 'some error', "\033[2J\033[H"], - $console->environment()->outputs(), - ); - $this->assertSame( - [], - $console->environment()->errors(), + $console + ->environment() + ->outputted() + ->map(static fn($chunk) => $chunk[0]->toString()) + ->toList(), ); } @@ -480,74 +382,47 @@ public function testSaidMessageIsChangedWhenTestsAreFailing() $trigger = new CodingStandard( $iteration = new Iteration, ); - - $os = $this->createMock(OperatingSystem::class); - $server = $this->createMock(Server::class); - $processes = $this->createMock(Processes::class); - $filesystem = $this->createMock(Filesystem::class); - $adapter = Adapter\InMemory::new(); - $adapter->add(File::named( + $adapter = Adapter::inMemory(); + $_ = $adapter->add(File::named( '.php_cs.dist', Content::none(), - )); + ))->unwrap(); + + $count = 0; + $os = OperatingSystem::new( + Config::new() + ->mountFilesystemVia(static fn() => Attempt::result($adapter)) + ->useServerControl(Server::via( + function($command) use (&$count) { + $this->assertSame( + match ($count) { + 0 => "vendor/bin/php-cs-fixer 'fix' '--diff' '--dry-run' '--diff-format' 'udiff'", + 1 => "say 'Coding Standard : wrong'", + }, + $command->toString(), + ); + + if ($count === 0) { + $this->assertSame('/somewhere/', $command->workingDirectory()->match( + static fn($path) => $path->toString(), + static fn() => null, + )); + } + + $builder = Builder::foreground(2); + $builder = match ($count) { + 0 => $builder->failed(), + 1 => $builder, + }; + ++$count; + + return Attempt::result($builder->build()); + }, + )), + ); - $os - ->method('filesystem') - ->willReturn($filesystem); - $filesystem - ->expects($this->once()) - ->method('mount') - ->with(Path::of('/somewhere/')) - ->willReturn($adapter); - $cs = $this->createMock(Process::class); - $say = $this->createMock(Process::class); - $os - ->method('control') - ->willReturn($server); - $server - ->method('processes') - ->willReturn($processes); - $processes - ->expects($matcher = $this->exactly(2)) - ->method('execute') - ->willReturnCallback(function($command) use ($matcher, $cs, $say) { - match ($matcher->numberOfInvocations()) { - 1 => $this->assertSame( - "vendor/bin/php-cs-fixer 'fix' '--diff' '--dry-run' '--diff-format' 'udiff'", - $command->toString(), - ), - 2 => $this->assertSame( - "say 'Coding Standard : wrong'", - $command->toString(), - ), - }; - - if ($matcher->numberOfInvocations() === 1) { - $this->assertSame('/somewhere/', $command->workingDirectory()->match( - static fn($path) => $path->toString(), - static fn() => null, - )); - } - - return match ($matcher->numberOfInvocations()) { - 1 => $cs, - 2 => $say, - }; - }); - $cs - ->expects($this->once()) - ->method('output') - ->willReturn(new Output\Output(Sequence::of())); - $cs - ->expects($this->once()) - ->method('wait') - ->willReturn(Either::left(new ExitCode(1))); - $say - ->expects($this->once()) - ->method('wait') - ->willReturn(Either::right(new SideEffect)); $console = Console::of( - Environment\InMemory::of( + Environment::inMemory( [], true, [], @@ -566,8 +441,14 @@ public function testSaidMessageIsChangedWhenTestsAreFailing() Set::of(Triggers::codingStandard), ); $console = $iteration->end($console); - $this->assertSame([], $console->environment()->outputs()); - $this->assertSame([], $console->environment()->errors()); + $this->assertSame( + [], + $console + ->environment() + ->outputted() + ->map(static fn($chunk) => $chunk[0]->toString()) + ->toList(), + ); } public function testNoMessageIsSpokenWhenUsingTheSilentOption() @@ -575,52 +456,40 @@ public function testNoMessageIsSpokenWhenUsingTheSilentOption() $trigger = new CodingStandard( $iteration = new Iteration, ); - - $os = $this->createMock(OperatingSystem::class); - $server = $this->createMock(Server::class); - $processes = $this->createMock(Processes::class); - $filesystem = $this->createMock(Filesystem::class); - $adapter = Adapter\InMemory::new(); - $adapter->add(File::named( + $adapter = Adapter::inMemory(); + $_ = $adapter->add(File::named( '.php_cs.dist', Content::none(), - )); + ))->unwrap(); + + $count = 0; + $os = OperatingSystem::new( + Config::new() + ->mountFilesystemVia(static fn() => Attempt::result($adapter)) + ->useServerControl(Server::via( + function($command) use (&$count) { + $this->assertSame( + match ($count) { + 0 => "vendor/bin/php-cs-fixer 'fix' '--diff' '--dry-run' '--diff-format' 'udiff'", + }, + $command->toString(), + ); + $this->assertSame('/somewhere/', $command->workingDirectory()->match( + static fn($path) => $path->toString(), + static fn() => null, + )); + + ++$count; + + return Attempt::result( + Builder::foreground(2)->build(), + ); + }, + )), + ); - $os - ->method('filesystem') - ->willReturn($filesystem); - $filesystem - ->expects($this->once()) - ->method('mount') - ->with(Path::of('/somewhere/')) - ->willReturn($adapter); - $os - ->method('control') - ->willReturn($server); - $server - ->method('processes') - ->willReturn($processes); - $processes - ->expects($this->once()) - ->method('execute') - ->with($this->callback(static function($command): bool { - return $command->toString() === "vendor/bin/php-cs-fixer 'fix' '--diff' '--dry-run' '--diff-format' 'udiff'" && - '/somewhere/' === $command->workingDirectory()->match( - static fn($path) => $path->toString(), - static fn() => null, - ); - })) - ->willReturn($process = $this->createMock(Process::class)); - $process - ->expects($this->once()) - ->method('wait') - ->willReturn(Either::right(new SideEffect)); - $process - ->expects($this->once()) - ->method('output') - ->willReturn(new Output\Output(Sequence::of())); $console = Console::of( - Environment\InMemory::of( + Environment::inMemory( [], true, ['--silent'], @@ -639,7 +508,13 @@ public function testNoMessageIsSpokenWhenUsingTheSilentOption() Set::of(Triggers::codingStandard), ); $console = $iteration->end($console); - $this->assertSame(["\033[2J\033[H"], $console->environment()->outputs()); - $this->assertSame([], $console->environment()->errors()); + $this->assertSame( + ["\033[2J\033[H"], + $console + ->environment() + ->outputted() + ->map(static fn($chunk) => $chunk[0]->toString()) + ->toList(), + ); } } diff --git a/tests/Trigger/ComposerUpdateTest.php b/tests/Trigger/ComposerUpdateTest.php index cf647c2..044ec12 100644 --- a/tests/Trigger/ComposerUpdateTest.php +++ b/tests/Trigger/ComposerUpdateTest.php @@ -9,12 +9,13 @@ Triggers, Activity, }; -use Innmind\OperatingSystem\OperatingSystem; +use Innmind\OperatingSystem\{ + OperatingSystem, + Config, +}; use Innmind\Server\Control\{ Server, - Server\Processes, - Server\Process, - Server\Process\Output, + Server\Process\Builder, }; use Innmind\CLI\{ Environment, @@ -23,9 +24,8 @@ Command\Options, }; use Innmind\Immutable\{ - Str, - Sequence, Set, + Attempt, }; use PHPUnit\Framework\TestCase; @@ -43,12 +43,9 @@ public function testDoNothingWhenNotOfExpectedType() { $trigger = new ComposerUpdate; - $os = $this->createMock(OperatingSystem::class); - $os - ->expects($this->never()) - ->method('control'); + $os = OperatingSystem::new(); $console = Console::of( - Environment\InMemory::of( + Environment::inMemory( [], true, [], @@ -71,12 +68,9 @@ public function testDoNothingWhenTriggerNotEnabled() { $trigger = new ComposerUpdate; - $os = $this->createMock(OperatingSystem::class); - $os - ->expects($this->never()) - ->method('control'); + $os = OperatingSystem::new(); $console = Console::of( - Environment\InMemory::of( + Environment::inMemory( ["\n"], true, [], @@ -95,11 +89,11 @@ public function testDoNothingWhenTriggerNotEnabled() ); $this->assertSame( [], - $console->environment()->outputs(), - ); - $this->assertSame( - [], - $console->environment()->errors(), + $console + ->environment() + ->outputted() + ->map(static fn($chunk) => $chunk[0]->toString()) + ->toList(), ); } @@ -107,36 +101,32 @@ public function testTriggerUpdateOnStart() { $trigger = new ComposerUpdate; - $os = $this->createMock(OperatingSystem::class); - $server = $this->createMock(Server::class); - $processes = $this->createMock(Processes::class); - - $os - ->method('control') - ->willReturn($server); - $server - ->method('processes') - ->willReturn($processes); - $processes - ->expects($this->once()) - ->method('execute') - ->with($this->callback(static function($command): bool { - return $command->toString() === "composer '--ansi' 'update'" && - '/somewhere/' === $command->workingDirectory()->match( + $os = OperatingSystem::new( + Config::new()->useServerControl(Server::via( + function($command) { + $this->assertSame( + "composer '--ansi' 'update'", + $command->toString(), + ); + $this->assertSame('/somewhere/', $command->workingDirectory()->match( static fn($path) => $path->toString(), static fn() => null, + )); + + return Attempt::result( + Builder::foreground(2) + ->success([ + ['some output', 'output'], + ['some error', 'error'], + ]) + ->build(), ); - })) - ->willReturn($process = $this->createMock(Process::class)); - $process - ->expects($this->once()) - ->method('output') - ->willReturn(new Output\Output(Sequence::of( - [Str::of('some output'), Output\Type::output], - [Str::of('some error'), Output\Type::error], - ))); + }, + )), + ); + $console = Console::of( - Environment\InMemory::of( + Environment::inMemory( ["\n"], true, [], @@ -155,11 +145,11 @@ public function testTriggerUpdateOnStart() ); $this->assertSame( ['Update dependencies? [Y/n] ', 'some output', 'some error', "Dependencies updated!\n"], - $console->environment()->outputs(), - ); - $this->assertSame( - [], - $console->environment()->errors(), + $console + ->environment() + ->outputted() + ->map(static fn($chunk) => $chunk[0]->toString()) + ->toList(), ); } @@ -167,12 +157,9 @@ public function testDoesntTriggerUpdateWhenNegativeResponse() { $trigger = new ComposerUpdate; - $os = $this->createMock(OperatingSystem::class); - $os - ->expects($this->never()) - ->method('control'); + $os = OperatingSystem::new(); $console = Console::of( - Environment\InMemory::of( + Environment::inMemory( ["n\n"], true, [], @@ -191,7 +178,11 @@ public function testDoesntTriggerUpdateWhenNegativeResponse() ); $this->assertSame( ['Update dependencies? [Y/n] '], - $console->environment()->outputs(), + $console + ->environment() + ->outputted() + ->map(static fn($chunk) => $chunk[0]->toString()) + ->toList(), ); } } diff --git a/tests/Trigger/DockerComposeTest.php b/tests/Trigger/DockerComposeTest.php index 6b8ace1..4cd33a5 100644 --- a/tests/Trigger/DockerComposeTest.php +++ b/tests/Trigger/DockerComposeTest.php @@ -11,12 +11,11 @@ }; use Innmind\OperatingSystem\{ OperatingSystem, - Filesystem, + Config, }; use Innmind\Server\Control\{ Server, - Server\Processes, - Server\Process, + Server\Process\Builder, }; use Innmind\CLI\{ Environment, @@ -29,11 +28,9 @@ File, File\Content, }; -use Innmind\Url\Path; use Innmind\Immutable\{ - Either, - SideEffect, Set, + Attempt, }; use PHPUnit\Framework\TestCase; @@ -51,15 +48,15 @@ public function testDoesntStartDockerComposeWhenNotStartActivity() { $trigger = new DockerCompose; - $os = $this->createMock(OperatingSystem::class); - $os - ->expects($this->never()) - ->method('filesystem'); - $os - ->expects($this->never()) - ->method('control'); + $os = OperatingSystem::new(); $console = Console::of( - $this->createMock(Environment::class), + Environment::inMemory( + [], + true, + [], + [], + '/path/to/project/vendor/package', + ), new Arguments, new Options, ); @@ -76,22 +73,16 @@ public function testDoesntStartDockerComposeWhenNoConfigFile() { $trigger = new DockerCompose; - $os = $this->createMock(OperatingSystem::class); - $filesystem = $this->createMock(Filesystem::class); - - $os - ->method('filesystem') - ->willReturn($filesystem); - $filesystem - ->expects($this->once()) - ->method('mount') - ->with(Path::of('/path/to/project/vendor/package/')) - ->willReturn(Adapter\InMemory::new()); - $os - ->expects($this->never()) - ->method('control'); + $count = 0; + $os = OperatingSystem::new( + Config::new() + ->mountFilesystemVia(static fn() => Attempt::result(Adapter::inMemory())) + ->useServerControl(Server::via( + static fn() => Attempt::error(new \Exception), + )), + ); $console = Console::of( - Environment\InMemory::of( + Environment::inMemory( [], true, [], @@ -114,15 +105,9 @@ public function testDoNothingWhenTriggerNotEnabled() { $trigger = new DockerCompose; - $os = $this->createMock(OperatingSystem::class); - $os - ->expects($this->never()) - ->method('filesystem'); - $os - ->expects($this->never()) - ->method('control'); + $os = OperatingSystem::new(); $console = Console::of( - Environment\InMemory::of( + Environment::inMemory( [], true, [], @@ -141,59 +126,48 @@ public function testDoNothingWhenTriggerNotEnabled() ); $this->assertSame( [], - $console->environment()->outputs(), - ); - $this->assertSame( - [], - $console->environment()->errors(), + $console + ->environment() + ->outputted() + ->toList(), ); } public function testStartDockerCompose() { $trigger = new DockerCompose; - - $os = $this->createMock(OperatingSystem::class); - $filesystem = $this->createMock(Filesystem::class); - $server = $this->createMock(Server::class); - $processes = $this->createMock(Processes::class); - $project = Adapter\InMemory::new(); - $project->add(File::named( + $project = Adapter::inMemory(); + $_ = $project->add(File::named( 'docker-compose.yml', Content::none(), - )); + ))->unwrap(); + + $os = OperatingSystem::new( + Config::new() + ->mountFilesystemVia(static fn() => Attempt::result($project)) + ->useServerControl(Server::via( + function($command) { + $this->assertSame( + "docker-compose 'up' '-d'", + $command->toString(), + ); + $this->assertSame( + '/path/to/project/vendor/package/', + $command->workingDirectory()->match( + static fn($path) => $path->toString(), + static fn() => null, + ), + ); + + return Attempt::result( + Builder::foreground(2)->build(), + ); + }, + )), + ); - $os - ->method('filesystem') - ->willReturn($filesystem); - $filesystem - ->expects($this->once()) - ->method('mount') - ->with(Path::of('/path/to/project/vendor/package/')) - ->willReturn($project); - $os - ->method('control') - ->willReturn($server); - $server - ->method('processes') - ->willReturn($processes); - $processes - ->expects($this->once()) - ->method('execute') - ->with($this->callback(static function($command): bool { - return $command->toString() === "docker-compose 'up' '-d'" && - '/path/to/project/vendor/package/' === $command->workingDirectory()->match( - static fn($path) => $path->toString(), - static fn() => null, - ); - })) - ->willReturn($process = $this->createMock(Process::class)); - $process - ->expects($this->once()) - ->method('wait') - ->willReturn(Either::right(new SideEffect)); $console = Console::of( - Environment\InMemory::of( + Environment::inMemory( [], true, [], diff --git a/tests/Trigger/PsalmTest.php b/tests/Trigger/PsalmTest.php index 349b9e5..da4b974 100644 --- a/tests/Trigger/PsalmTest.php +++ b/tests/Trigger/PsalmTest.php @@ -12,10 +12,7 @@ }; use Innmind\Server\Control\{ Server, - Server\Processes, - Server\Process, - Server\Process\Output, - Server\Process\ExitCode, + Server\Process\Builder, }; use Innmind\CLI\{ Environment, @@ -23,10 +20,9 @@ Command\Arguments, Command\Options, }; -use Innmind\Url\Path; use Innmind\OperatingSystem\{ OperatingSystem, - Filesystem, + Config, }; use Innmind\Filesystem\{ Adapter, @@ -34,12 +30,9 @@ File\Content, }; use Innmind\Immutable\{ - Sequence, - Str, - Either, - SideEffect, Map, Set, + Attempt, }; use PHPUnit\Framework\TestCase; @@ -56,15 +49,15 @@ public function testInterface() public function testDoNothingWhenNotOfExpectedType() { $trigger = new Psalm(new Iteration); - $os = $this->createMock(OperatingSystem::class); - $os - ->expects($this->never()) - ->method('filesystem'); - $os - ->expects($this->never()) - ->method('control'); + $os = OperatingSystem::new(); $console = Console::of( - $this->createMock(Environment::class), + Environment::inMemory( + [], + true, + [], + [], + '/somewhere', + ), new Arguments, new Options, ); @@ -80,21 +73,13 @@ public function testDoNothingWhenNotOfExpectedType() public function testDoNothingWhenPsalmNotInstalled() { $trigger = new Psalm(new Iteration); - $os = $this->createMock(OperatingSystem::class); - $filesystem = $this->createMock(Filesystem::class); - - $os - ->method('filesystem') - ->willReturn($filesystem); - $filesystem - ->expects($this->once()) - ->method('mount') - ->willReturn(Adapter\InMemory::new()); - $os - ->expects($this->never()) - ->method('control'); + $os = OperatingSystem::new( + Config::new() + ->mountFilesystemVia(static fn() => Attempt::result(Adapter::inMemory())), + ); + $console = Console::of( - Environment\InMemory::of( + Environment::inMemory( [], true, [], @@ -116,15 +101,9 @@ public function testDoNothingWhenPsalmNotInstalled() public function testDoNothingWhenTriggerNotEnabled() { $trigger = new Psalm(new Iteration); - $os = $this->createMock(OperatingSystem::class); - $os - ->expects($this->never()) - ->method('filesystem'); - $os - ->expects($this->never()) - ->method('control'); + $os = OperatingSystem::new(); $console = Console::of( - Environment\InMemory::of( + Environment::inMemory( [], true, [], @@ -143,11 +122,11 @@ public function testDoNothingWhenTriggerNotEnabled() ); $this->assertSame( [], - $console->environment()->outputs(), - ); - $this->assertSame( - [], - $console->environment()->errors(), + $console + ->environment() + ->outputted() + ->map(static fn($chunk) => $chunk[0]->toString()) + ->toList(), ); } @@ -156,78 +135,52 @@ public function testTriggerTestsSuiteWhenSourcesModified() $trigger = new Psalm( $iteration = new Iteration, ); - $os = $this->createMock(OperatingSystem::class); - $server = $this->createMock(Server::class); - $processes = $this->createMock(Processes::class); - $filesystem = $this->createMock(Filesystem::class); - $adapter = Adapter\InMemory::new(); - $adapter->add(File::named( + $adapter = Adapter::inMemory(); + $_ = $adapter->add(File::named( 'psalm.xml', Content::none(), - )); + ))->unwrap(); + + $count = 0; + $os = OperatingSystem::new( + Config::new() + ->mountFilesystemVia(static fn() => Attempt::result($adapter)) + ->useServerControl(Server::via( + function($command) use (&$count) { + $this->assertSame( + match ($count) { + 0 => "vendor/bin/psalm '--no-cache'", + 1 => "say 'Psalm : ok'", + }, + $command->toString(), + ); + + if ($count === 0) { + $this->assertSame('/somewhere/', $command->workingDirectory()->match( + static fn($path) => $path->toString(), + static fn() => null, + )); + } + + $builder = Builder::foreground(2); + // we say here that psalm is successful even though we have an error in + // the output in order to verify the terminal is cleared on success + $builder = match ($count) { + 0 => $builder->success([ + ['some output', 'output'], + ['some error', 'error'], + ]), + 1 => $builder, + }; + ++$count; + + return Attempt::result($builder->build()); + }, + )), + ); - $os - ->method('filesystem') - ->willReturn($filesystem); - $filesystem - ->expects($this->once()) - ->method('mount') - ->with(Path::of('/somewhere/')) - ->willReturn($adapter); - $psalm = $this->createMock(Process::class); - $say = $this->createMock(Process::class); - $os - ->method('control') - ->willReturn($server); - $server - ->method('processes') - ->willReturn($processes); - $processes - ->expects($matcher = $this->exactly(2)) - ->method('execute') - ->willReturnCallback(function($command) use ($matcher, $psalm, $say) { - match ($matcher->numberOfInvocations()) { - 1 => $this->assertSame( - "vendor/bin/psalm '--no-cache'", - $command->toString(), - ), - 2 => $this->assertSame( - "say 'Psalm : ok'", - $command->toString(), - ), - }; - - if ($matcher->numberOfInvocations() === 1) { - $this->assertSame('/somewhere/', $command->workingDirectory()->match( - static fn($path) => $path->toString(), - static fn() => null, - )); - } - - return match ($matcher->numberOfInvocations()) { - 1 => $psalm, - 2 => $say, - }; - }); - $psalm - ->expects($this->once()) - ->method('output') - ->willReturn(new Output\Output(Sequence::of( - [Str::of('some output'), Output\Type::output], - [Str::of('some error'), Output\Type::error], - ))); - // we say here that psalm is successful even though we have an error in - // the output in order to verify the terminal is cleared on success - $psalm - ->expects($this->once()) - ->method('wait') - ->willReturn(Either::right(new SideEffect)); - $say - ->expects($this->once()) - ->method('wait') - ->willReturn(Either::right(new SideEffect)); $console = Console::of( - Environment\InMemory::of( + Environment::inMemory( [], true, [], @@ -248,11 +201,11 @@ public function testTriggerTestsSuiteWhenSourcesModified() $console = $iteration->end($console); $this->assertSame( ['some output', 'some error', "\033[2J\033[H"], - $console->environment()->outputs(), - ); - $this->assertSame( - [], - $console->environment()->errors(), + $console + ->environment() + ->outputted() + ->map(static fn($chunk) => $chunk[0]->toString()) + ->toList(), ); } @@ -261,73 +214,44 @@ public function testDoesnClearTerminalOnSuccessfullTestWhenSpecifiedOptionProvid $trigger = new Psalm( $iteration = new Iteration, ); - $os = $this->createMock(OperatingSystem::class); - $server = $this->createMock(Server::class); - $processes = $this->createMock(Processes::class); - $filesystem = $this->createMock(Filesystem::class); - $adapter = Adapter\InMemory::new(); - $adapter->add(File::named( + $adapter = Adapter::inMemory(); + $_ = $adapter->add(File::named( 'psalm.xml', Content::none(), - )); + ))->unwrap(); + + $count = 0; + $os = OperatingSystem::new( + Config::new() + ->mountFilesystemVia(static fn() => Attempt::result($adapter)) + ->useServerControl(Server::via( + function($command) use (&$count) { + $this->assertSame( + match ($count) { + 0 => "vendor/bin/psalm '--no-cache'", + 1 => "say 'Psalm : ok'", + }, + $command->toString(), + ); + + if ($count === 0) { + $this->assertSame('/somewhere/', $command->workingDirectory()->match( + static fn($path) => $path->toString(), + static fn() => null, + )); + } + + ++$count; + + return Attempt::result( + Builder::foreground(2)->build(), + ); + }, + )), + ); - $os - ->method('filesystem') - ->willReturn($filesystem); - $filesystem - ->expects($this->once()) - ->method('mount') - ->with(Path::of('/somewhere/')) - ->willReturn($adapter); - $psalm = $this->createMock(Process::class); - $say = $this->createMock(Process::class); - $os - ->method('control') - ->willReturn($server); - $server - ->method('processes') - ->willReturn($processes); - $processes - ->expects($matcher = $this->exactly(2)) - ->method('execute') - ->willReturnCallback(function($command) use ($matcher, $psalm, $say) { - match ($matcher->numberOfInvocations()) { - 1 => $this->assertSame( - "vendor/bin/psalm '--no-cache'", - $command->toString(), - ), - 2 => $this->assertSame( - "say 'Psalm : ok'", - $command->toString(), - ), - }; - - if ($matcher->numberOfInvocations() === 1) { - $this->assertSame('/somewhere/', $command->workingDirectory()->match( - static fn($path) => $path->toString(), - static fn() => null, - )); - } - - return match ($matcher->numberOfInvocations()) { - 1 => $psalm, - 2 => $say, - }; - }); - $psalm - ->expects($this->once()) - ->method('output') - ->willReturn(new Output\Output(Sequence::of())); - $psalm - ->expects($this->once()) - ->method('wait') - ->willReturn(Either::right(new SideEffect)); - $say - ->expects($this->once()) - ->method('wait') - ->willReturn(Either::right(new SideEffect)); $console = Console::of( - Environment\InMemory::of( + Environment::inMemory( [], true, ['--keep-output'], @@ -346,7 +270,14 @@ public function testDoesnClearTerminalOnSuccessfullTestWhenSpecifiedOptionProvid Set::of(Triggers::psalm), ); $console = $iteration->end($console); - $this->assertSame([], $console->environment()->outputs()); + $this->assertSame( + [], + $console + ->environment() + ->outputted() + ->map(static fn($chunk) => $chunk[0]->toString()) + ->toList(), + ); } public function testSaidMessageIsChangedWhenTestsAreFailing() @@ -354,73 +285,47 @@ public function testSaidMessageIsChangedWhenTestsAreFailing() $trigger = new Psalm( $iteration = new Iteration, ); - $os = $this->createMock(OperatingSystem::class); - $server = $this->createMock(Server::class); - $processes = $this->createMock(Processes::class); - $filesystem = $this->createMock(Filesystem::class); - $adapter = Adapter\InMemory::new(); - $adapter->add(File::named( + $adapter = Adapter::inMemory(); + $_ = $adapter->add(File::named( 'psalm.xml', Content::none(), - )); + ))->unwrap(); + + $count = 0; + $os = OperatingSystem::new( + Config::new() + ->mountFilesystemVia(static fn() => Attempt::result($adapter)) + ->useServerControl(Server::via( + function($command) use (&$count) { + $this->assertSame( + match ($count) { + 0 => "vendor/bin/psalm '--no-cache'", + 1 => "say 'Psalm : failing'", + }, + $command->toString(), + ); + + if ($count === 0) { + $this->assertSame('/somewhere/', $command->workingDirectory()->match( + static fn($path) => $path->toString(), + static fn() => null, + )); + } + + $builder = Builder::foreground(2); + $builder = match ($count) { + 0 => $builder->failed(), + 1 => $builder, + }; + ++$count; + + return Attempt::result($builder->build()); + }, + )), + ); - $os - ->method('filesystem') - ->willReturn($filesystem); - $filesystem - ->expects($this->once()) - ->method('mount') - ->with(Path::of('/somewhere/')) - ->willReturn($adapter); - $psalm = $this->createMock(Process::class); - $say = $this->createMock(Process::class); - $os - ->method('control') - ->willReturn($server); - $server - ->method('processes') - ->willReturn($processes); - $processes - ->expects($matcher = $this->exactly(2)) - ->method('execute') - ->willReturnCallback(function($command) use ($matcher, $psalm, $say) { - match ($matcher->numberOfInvocations()) { - 1 => $this->assertSame( - "vendor/bin/psalm '--no-cache'", - $command->toString(), - ), - 2 => $this->assertSame( - "say 'Psalm : failing'", - $command->toString(), - ), - }; - - if ($matcher->numberOfInvocations() === 1) { - $this->assertSame('/somewhere/', $command->workingDirectory()->match( - static fn($path) => $path->toString(), - static fn() => null, - )); - } - - return match ($matcher->numberOfInvocations()) { - 1 => $psalm, - 2 => $say, - }; - }); - $psalm - ->expects($this->once()) - ->method('output') - ->willReturn(new Output\Output(Sequence::of())); - $psalm - ->expects($this->once()) - ->method('wait') - ->willReturn(Either::left(new ExitCode(1))); - $say - ->expects($this->once()) - ->method('wait') - ->willReturn(Either::right(new SideEffect)); $console = Console::of( - Environment\InMemory::of( + Environment::inMemory( [], true, [], @@ -439,7 +344,14 @@ public function testSaidMessageIsChangedWhenTestsAreFailing() Set::of(Triggers::psalm), ); $console = $iteration->end($console); - $this->assertSame([], $console->environment()->outputs()); + $this->assertSame( + [], + $console + ->environment() + ->outputted() + ->map(static fn($chunk) => $chunk[0]->toString()) + ->toList(), + ); } public function testNoMessageIsSpokenWhenUsingTheSilentOption() @@ -447,51 +359,41 @@ public function testNoMessageIsSpokenWhenUsingTheSilentOption() $trigger = new Psalm( $iteration = new Iteration, ); - $os = $this->createMock(OperatingSystem::class); - $server = $this->createMock(Server::class); - $processes = $this->createMock(Processes::class); - $filesystem = $this->createMock(Filesystem::class); - $adapter = Adapter\InMemory::new(); - $adapter->add(File::named( + $adapter = Adapter::inMemory(); + $_ = $adapter->add(File::named( 'psalm.xml', Content::none(), - )); + ))->unwrap(); + + $count = 0; + $os = OperatingSystem::new( + Config::new() + ->mountFilesystemVia(static fn() => Attempt::result($adapter)) + ->useServerControl(Server::via( + function($command) use (&$count) { + $this->assertSame( + match ($count) { + 0 => "vendor/bin/psalm '--no-cache'", + }, + $command->toString(), + ); + + $this->assertSame('/somewhere/', $command->workingDirectory()->match( + static fn($path) => $path->toString(), + static fn() => null, + )); + + ++$count; + + return Attempt::result( + Builder::foreground(2)->build(), + ); + }, + )), + ); - $os - ->method('filesystem') - ->willReturn($filesystem); - $filesystem - ->expects($this->once()) - ->method('mount') - ->with(Path::of('/somewhere/')) - ->willReturn($adapter); - $os - ->method('control') - ->willReturn($server); - $server - ->method('processes') - ->willReturn($processes); - $processes - ->expects($this->once()) - ->method('execute') - ->with($this->callback(static function($command): bool { - return $command->toString() === "vendor/bin/psalm '--no-cache'" && - '/somewhere/' === $command->workingDirectory()->match( - static fn($path) => $path->toString(), - static fn() => null, - ); - })) - ->willReturn($process = $this->createMock(Process::class)); - $process - ->expects($this->once()) - ->method('wait') - ->willReturn(Either::right(new SideEffect)); - $process - ->expects($this->once()) - ->method('output') - ->willReturn(new Output\Output(Sequence::of())); $console = Console::of( - Environment\InMemory::of( + Environment::inMemory( [], true, ['--silent'], @@ -510,7 +412,13 @@ public function testNoMessageIsSpokenWhenUsingTheSilentOption() Set::of(Triggers::psalm), ); $console = $iteration->end($console); - $this->assertSame(["\033[2J\033[H"], $console->environment()->outputs()); - $this->assertSame([], $console->environment()->errors()); + $this->assertSame( + ["\033[2J\033[H"], + $console + ->environment() + ->outputted() + ->map(static fn($chunk) => $chunk[0]->toString()) + ->toList(), + ); } } diff --git a/tests/Trigger/TestsTest.php b/tests/Trigger/TestsTest.php index 28bfe83..4110cc8 100644 --- a/tests/Trigger/TestsTest.php +++ b/tests/Trigger/TestsTest.php @@ -12,14 +12,11 @@ }; use Innmind\OperatingSystem\{ OperatingSystem, - Filesystem, + Config, }; use Innmind\Server\Control\{ Server, - Server\Processes, - Server\Process, - Server\Process\Output, - Server\Process\ExitCode, + Server\Process\Builder, }; use Innmind\CLI\{ Environment, @@ -33,12 +30,9 @@ File\Content, }; use Innmind\Immutable\{ - Sequence, - Str, - Either, - SideEffect, Map, Set as ISet, + Attempt, }; use PHPUnit\Framework\TestCase; use Innmind\BlackBox\{ @@ -63,16 +57,15 @@ public function testInterface() public function testDoNothingWhenNotOfExpectedType() { $trigger = new Tests(new Iteration); - $os = $this->createMock(OperatingSystem::class); - - $os - ->expects($this->never()) - ->method('filesystem'); - $os - ->expects($this->never()) - ->method('control'); + $os = OperatingSystem::new(); $console = Console::of( - $this->createMock(Environment::class), + Environment::inMemory( + [], + true, + [], + [], + '/somewhere', + ), new Arguments, new Options, ); @@ -91,15 +84,9 @@ public function testDoNothingWhenTriggerNotEnabled() ->forAll(Set::of(...Activity::cases())) ->then(function($type) { $trigger = new Tests(new Iteration); - $os = $this->createMock(OperatingSystem::class); - $os - ->expects($this->never()) - ->method('filesystem'); - $os - ->expects($this->never()) - ->method('control'); + $os = OperatingSystem::new(); $console = Console::of( - Environment\InMemory::of( + Environment::inMemory( [], true, [], @@ -118,11 +105,10 @@ public function testDoNothingWhenTriggerNotEnabled() ); $this->assertSame( [], - $console->environment()->outputs(), - ); - $this->assertSame( - [], - $console->environment()->errors(), + $console + ->environment() + ->outputted() + ->toList(), ); }); } @@ -139,78 +125,52 @@ public function testTriggerTestsSuiteWhenActivity() $trigger = new Tests( $iteration = new Iteration, ); - $os = $this->createMock(OperatingSystem::class); - $filesystem = $this->createMock(Filesystem::class); - $server = $this->createMock(Server::class); - $processes = $this->createMock(Processes::class); - $adapter = Adapter\InMemory::new(); - $adapter->add(File::named( + $adapter = Adapter::inMemory(); + $_ = $adapter->add(File::named( 'phpunit.xml.dist', Content::none(), - )); - - $os - ->method('filesystem') - ->willReturn($filesystem); - $filesystem - ->expects($this->once()) - ->method('mount') - ->willReturn($adapter); - $os - ->method('control') - ->willReturn($server); - $server - ->method('processes') - ->willReturn($processes); - $tests = $this->createMock(Process::class); - $say = $this->createMock(Process::class); - $processes - ->expects($matcher = $this->exactly(2)) - ->method('execute') - ->willReturnCallback(function($command) use ($matcher, $tests, $say) { - match ($matcher->numberOfInvocations()) { - 1 => $this->assertSame( - "vendor/bin/phpunit '--colors=always' '--fail-on-warning'", - $command->toString(), - ), - 2 => $this->assertSame( - "say 'PHPUnit : ok'", - $command->toString(), - ), - }; - - if ($matcher->numberOfInvocations() === 1) { - $this->assertSame('/somewhere/', $command->workingDirectory()->match( - static fn($path) => $path->toString(), - static fn() => null, - )); - } - - return match ($matcher->numberOfInvocations()) { - 1 => $tests, - 2 => $say, - }; - }); - $tests - ->expects($this->once()) - ->method('output') - ->willReturn(new Output\Output(Sequence::of( - [Str::of('some output'), Output\Type::output], - [Str::of('some error'), Output\Type::error], - ))); - // we say here that tests are successful even though we have an - // error in the output in order to verify the terminal is cleared - // on success - $tests - ->expects($this->once()) - ->method('wait') - ->willReturn(Either::right(new SideEffect)); - $say - ->expects($this->once()) - ->method('wait') - ->willReturn(Either::right(new SideEffect)); + ))->unwrap(); + + $count = 0; + $os = OperatingSystem::new( + Config::new() + ->mountFilesystemVia(static fn() => Attempt::result($adapter)) + ->useServerControl(Server::via( + function($command) use (&$count) { + $this->assertSame( + match ($count) { + 0 => "vendor/bin/phpunit '--colors=always' '--fail-on-warning'", + 1 => "say 'PHPUnit : ok'", + }, + $command->toString(), + ); + + if ($count === 0) { + $this->assertSame('/somewhere/', $command->workingDirectory()->match( + static fn($path) => $path->toString(), + static fn() => null, + )); + } + + $builder = Builder::foreground(2); + // we say here that tests are successful even though we have an + // error in the output in order to verify the terminal is cleared + // on success + $builder = match ($count) { + 0 => $builder->success([ + ['some output', 'output'], + ['some error', 'error'], + ]), + 1 => $builder, + }; + ++$count; + + return Attempt::result($builder->build()); + }, + )), + ); $console = Console::of( - Environment\InMemory::of( + Environment::inMemory( [], true, [], @@ -231,11 +191,11 @@ public function testTriggerTestsSuiteWhenActivity() $console = $iteration->end($console); $this->assertSame( ['some output', 'some error', "\033[2J\033[H"], - $console->environment()->outputs(), - ); - $this->assertSame( - [], - $console->environment()->errors(), + $console + ->environment() + ->outputted() + ->map(static fn($chunk) => $chunk[0]->toString()) + ->toList(), ); }); } @@ -252,30 +212,19 @@ public function testDoesntTriggerWhenNoPHPUnitFile() $trigger = new Tests( $iteration = new Iteration, ); - $os = $this->createMock(OperatingSystem::class); - $filesystem = $this->createMock(Filesystem::class); - $server = $this->createMock(Server::class); - $processes = $this->createMock(Processes::class); - $adapter = Adapter\InMemory::new(); - - $os - ->method('filesystem') - ->willReturn($filesystem); - $filesystem - ->expects($this->once()) - ->method('mount') - ->willReturn($adapter); - $os - ->method('control') - ->willReturn($server); - $server - ->method('processes') - ->willReturn($processes); - $processes - ->expects($this->never()) - ->method('execute'); + $adapter = Adapter::inMemory(); + + $count = 0; + $os = OperatingSystem::new( + Config::new() + ->mountFilesystemVia(static fn() => Attempt::result($adapter)) + ->useServerControl(Server::via( + static fn() => Attempt::error(new \Exception), + )), + ); + $console = Console::of( - Environment\InMemory::of( + Environment::inMemory( [], true, [], @@ -296,11 +245,11 @@ public function testDoesntTriggerWhenNoPHPUnitFile() $console = $iteration->end($console); $this->assertSame( ["\033[2J\033[H"], - $console->environment()->outputs(), - ); - $this->assertSame( - [], - $console->environment()->errors(), + $console + ->environment() + ->outputted() + ->map(static fn($chunk) => $chunk[0]->toString()) + ->toList(), ); }); } @@ -310,73 +259,44 @@ public function testDoesntClearTerminalOnSuccessfullTestWhenSpecifiedOptionProvi $trigger = new Tests( $iteration = new Iteration, ); - $os = $this->createMock(OperatingSystem::class); - $filesystem = $this->createMock(Filesystem::class); - $server = $this->createMock(Server::class); - $processes = $this->createMock(Processes::class); - $adapter = Adapter\InMemory::new(); - $adapter->add(File::named( + $adapter = Adapter::inMemory(); + $_ = $adapter->add(File::named( 'phpunit.xml.dist', Content::none(), - )); + ))->unwrap(); + + $count = 0; + $os = OperatingSystem::new( + Config::new() + ->mountFilesystemVia(static fn() => Attempt::result($adapter)) + ->useServerControl(Server::via( + function($command) use (&$count) { + $this->assertSame( + match ($count) { + 0 => "vendor/bin/phpunit '--colors=always' '--fail-on-warning'", + 1 => "say 'PHPUnit : ok'", + }, + $command->toString(), + ); + + if ($count === 0) { + $this->assertSame('/somewhere/', $command->workingDirectory()->match( + static fn($path) => $path->toString(), + static fn() => null, + )); + } + + ++$count; + + return Attempt::result( + Builder::foreground(2)->build(), + ); + }, + )), + ); - $os - ->method('filesystem') - ->willReturn($filesystem); - $filesystem - ->expects($this->once()) - ->method('mount') - ->willReturn($adapter); - $os - ->method('control') - ->willReturn($server); - $server - ->method('processes') - ->willReturn($processes); - - $tests = $this->createMock(Process::class); - $say = $this->createMock(Process::class); - $processes - ->expects($matcher = $this->exactly(2)) - ->method('execute') - ->willReturnCallback(function($command) use ($matcher, $tests, $say) { - match ($matcher->numberOfInvocations()) { - 1 => $this->assertSame( - "vendor/bin/phpunit '--colors=always' '--fail-on-warning'", - $command->toString(), - ), - 2 => $this->assertSame( - "say 'PHPUnit : ok'", - $command->toString(), - ), - }; - - if ($matcher->numberOfInvocations() === 1) { - $this->assertSame('/somewhere/', $command->workingDirectory()->match( - static fn($path) => $path->toString(), - static fn() => null, - )); - } - - return match ($matcher->numberOfInvocations()) { - 1 => $tests, - 2 => $say, - }; - }); - $tests - ->expects($this->once()) - ->method('wait') - ->willReturn(Either::right(new SideEffect)); - $tests - ->expects($this->once()) - ->method('output') - ->willReturn(new Output\Output(Sequence::of())); - $say - ->expects($this->once()) - ->method('wait') - ->willReturn(Either::right(new SideEffect)); $console = Console::of( - Environment\InMemory::of( + Environment::inMemory( [], true, ['--keep-output'], @@ -395,7 +315,14 @@ public function testDoesntClearTerminalOnSuccessfullTestWhenSpecifiedOptionProvi ISet::of(Triggers::tests), ); $console = $iteration->end($console); - $this->assertSame([], $console->environment()->outputs()); + $this->assertSame( + [], + $console + ->environment() + ->outputted() + ->map(static fn($chunk) => $chunk[0]->toString()) + ->toList(), + ); } public function testSaidMessageIsChangedWhenTestsAreFailing() @@ -403,73 +330,47 @@ public function testSaidMessageIsChangedWhenTestsAreFailing() $trigger = new Tests( $iteration = new Iteration, ); - $os = $this->createMock(OperatingSystem::class); - $filesystem = $this->createMock(Filesystem::class); - $server = $this->createMock(Server::class); - $processes = $this->createMock(Processes::class); - $adapter = Adapter\InMemory::new(); - $adapter->add(File::named( + $adapter = Adapter::inMemory(); + $_ = $adapter->add(File::named( 'phpunit.xml.dist', Content::none(), - )); + ))->unwrap(); + + $count = 0; + $os = OperatingSystem::new( + Config::new() + ->mountFilesystemVia(static fn() => Attempt::result($adapter)) + ->useServerControl(Server::via( + function($command) use (&$count) { + $this->assertSame( + match ($count) { + 0 => "vendor/bin/phpunit '--colors=always' '--fail-on-warning'", + 1 => "say 'PHPUnit : failing'", + }, + $command->toString(), + ); + + if ($count === 0) { + $this->assertSame('/somewhere/', $command->workingDirectory()->match( + static fn($path) => $path->toString(), + static fn() => null, + )); + } + + $builder = Builder::foreground(2); + $builder = match ($count) { + 0 => $builder->failed(), + 1 => $builder, + }; + ++$count; + + return Attempt::result($builder->build()); + }, + )), + ); - $os - ->method('filesystem') - ->willReturn($filesystem); - $filesystem - ->expects($this->once()) - ->method('mount') - ->willReturn($adapter); - $os - ->method('control') - ->willReturn($server); - $server - ->method('processes') - ->willReturn($processes); - - $tests = $this->createMock(Process::class); - $say = $this->createMock(Process::class); - $processes - ->expects($matcher = $this->exactly(2)) - ->method('execute') - ->willReturnCallback(function($command) use ($matcher, $tests, $say) { - match ($matcher->numberOfInvocations()) { - 1 => $this->assertSame( - "vendor/bin/phpunit '--colors=always' '--fail-on-warning'", - $command->toString(), - ), - 2 => $this->assertSame( - "say 'PHPUnit : failing'", - $command->toString(), - ), - }; - - if ($matcher->numberOfInvocations() === 1) { - $this->assertSame('/somewhere/', $command->workingDirectory()->match( - static fn($path) => $path->toString(), - static fn() => null, - )); - } - - return match ($matcher->numberOfInvocations()) { - 1 => $tests, - 2 => $say, - }; - }); - $tests - ->expects($this->once()) - ->method('output') - ->willReturn(new Output\Output(Sequence::of())); - $tests - ->expects($this->once()) - ->method('wait') - ->willReturn(Either::left(new ExitCode(1))); - $say - ->expects($this->once()) - ->method('wait') - ->willReturn(Either::right(new SideEffect)); $console = Console::of( - Environment\InMemory::of( + Environment::inMemory( [], true, [], @@ -488,7 +389,14 @@ public function testSaidMessageIsChangedWhenTestsAreFailing() ISet::of(Triggers::tests), ); $console = $iteration->end($console); - $this->assertSame([], $console->environment()->outputs()); + $this->assertSame( + [], + $console + ->environment() + ->outputted() + ->map(static fn($chunk) => $chunk[0]->toString()) + ->toList(), + ); } public function testNoMessageIsSpokenWhenUsingTheSilentOption() @@ -496,50 +404,41 @@ public function testNoMessageIsSpokenWhenUsingTheSilentOption() $trigger = new Tests( $iteration = new Iteration, ); - $os = $this->createMock(OperatingSystem::class); - $filesystem = $this->createMock(Filesystem::class); - $server = $this->createMock(Server::class); - $processes = $this->createMock(Processes::class); - $adapter = Adapter\InMemory::new(); - $adapter->add(File::named( + $adapter = Adapter::inMemory(); + $_ = $adapter->add(File::named( 'phpunit.xml.dist', Content::none(), - )); + ))->unwrap(); + + $count = 0; + $os = OperatingSystem::new( + Config::new() + ->mountFilesystemVia(static fn() => Attempt::result($adapter)) + ->useServerControl(Server::via( + function($command) use (&$count) { + $this->assertSame( + match ($count) { + 0 => "vendor/bin/phpunit '--colors=always' '--fail-on-warning'", + }, + $command->toString(), + ); + + $this->assertSame('/somewhere/', $command->workingDirectory()->match( + static fn($path) => $path->toString(), + static fn() => null, + )); + + ++$count; + + return Attempt::result( + Builder::foreground(2)->build(), + ); + }, + )), + ); - $os - ->method('filesystem') - ->willReturn($filesystem); - $filesystem - ->expects($this->once()) - ->method('mount') - ->willReturn($adapter); - $os - ->method('control') - ->willReturn($server); - $server - ->method('processes') - ->willReturn($processes); - $processes - ->expects($this->once()) - ->method('execute') - ->with($this->callback(static function($command): bool { - return $command->toString() === "vendor/bin/phpunit '--colors=always' '--fail-on-warning'" && - '/somewhere/' === $command->workingDirectory()->match( - static fn($path) => $path->toString(), - static fn() => null, - ); - })) - ->willReturn($process = $this->createMock(Process::class)); - $process - ->expects($this->once()) - ->method('wait') - ->willReturn(Either::right(new SideEffect)); - $process - ->expects($this->once()) - ->method('output') - ->willReturn(new Output\Output(Sequence::of())); $console = Console::of( - Environment\InMemory::of( + Environment::inMemory( [], true, ['--silent'], @@ -558,7 +457,13 @@ public function testNoMessageIsSpokenWhenUsingTheSilentOption() ISet::of(Triggers::tests), ); $console = $iteration->end($console); - $this->assertSame(["\033[2J\033[H"], $console->environment()->outputs()); - $this->assertSame([], $console->environment()->errors()); + $this->assertSame( + ["\033[2J\033[H"], + $console + ->environment() + ->outputted() + ->map(static fn($chunk) => $chunk[0]->toString()) + ->toList(), + ); } } From a6919c63907a93853c772ff5d910448b593fb9f3 Mon Sep 17 00:00:00 2001 From: Baptiste Langlade Date: Sun, 22 Feb 2026 17:17:20 +0100 Subject: [PATCH 2/5] fix php version to run the CS --- .github/workflows/ci.yml | 2 -- 1 file changed, 2 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index adb8ae9..5820e81 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -34,5 +34,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' From a30bf81726ec475afc082636c96f67c7bdfdddab Mon Sep 17 00:00:00 2001 From: Baptiste Langlade Date: Sun, 22 Feb 2026 17:42:49 +0100 Subject: [PATCH 3/5] mock the processes in order to test the watchers --- tests/Agent/WatchFixturesTest.php | 30 ++++++++++++++++++--- tests/Agent/WatchProofsTest.php | 30 ++++++++++++++++++--- tests/Agent/WatchPropertiesTest.php | 30 ++++++++++++++++++--- tests/Agent/WatchSourcesTest.php | 42 +++++++++++++++++++++++++---- tests/Agent/WatchTestsTest.php | 42 +++++++++++++++++++++++++---- 5 files changed, 155 insertions(+), 19 deletions(-) diff --git a/tests/Agent/WatchFixturesTest.php b/tests/Agent/WatchFixturesTest.php index b988d35..a4e30cf 100644 --- a/tests/Agent/WatchFixturesTest.php +++ b/tests/Agent/WatchFixturesTest.php @@ -16,13 +16,19 @@ OperatingSystem, Config, }; +use Innmind\Server\Control\{ + Server, + Server\Process\Builder, +}; use Innmind\Filesystem\{ Adapter, Directory, }; -use Innmind\FileWatch\Watch; use Innmind\Url\Path; -use Innmind\Immutable\Set; +use Innmind\Immutable\{ + Set, + Attempt, +}; use PHPUnit\Framework\TestCase; class WatchFixturesTest extends TestCase @@ -44,10 +50,28 @@ public function testSendMessageWhenFixturesAreModified() ->add(Directory::named('fixtures')) ->unwrap(); + $count = 0; $os = OperatingSystem::new( Config::new() ->mountFilesystemVia(static fn() => Attempt::result($adapter)) - ->useFileWatch(Watch::via()), // todo simulate file change + ->useServerControl(Server::via( + function($command) use (&$count) { + $this->assertSame( + "find '/vendor/package/fixtures/' '-type' 'f' | xargs '-n' '1' '-r' 'stat' '-f' '%Sm %N' '-t' '%Y-%m-%dT%H-%M-%S'", + $command->toString(), + ); + + $builder = Builder::foreground(2); + $builder = match ($count) { + 0 => $builder->success([['output', 'output']]), + 1 => $builder->success([['changed', 'output']]), + 2 => $builder->failed(), + }; + ++$count; + + return Attempt::result($builder->build()); + }, + )), ); $activities = Activities::new( diff --git a/tests/Agent/WatchProofsTest.php b/tests/Agent/WatchProofsTest.php index 6b2ed9c..89d9efa 100644 --- a/tests/Agent/WatchProofsTest.php +++ b/tests/Agent/WatchProofsTest.php @@ -16,13 +16,19 @@ OperatingSystem, Config, }; +use Innmind\Server\Control\{ + Server, + Server\Process\Builder, +}; use Innmind\Filesystem\{ Adapter, Directory, }; -use Innmind\FileWatch\Watch; use Innmind\Url\Path; -use Innmind\Immutable\Set; +use Innmind\Immutable\{ + Set, + Attempt, +}; use PHPUnit\Framework\TestCase; class WatchProofsTest extends TestCase @@ -44,10 +50,28 @@ public function testSendMessageWhenProofsAreModified() ->add(Directory::named('proofs')) ->unwrap(); + $count = 0; $os = OperatingSystem::new( Config::new() ->mountFilesystemVia(static fn() => Attempt::result($adapter)) - ->useFileWatch(Watch::via()), // todo simulate file change + ->useServerControl(Server::via( + function($command) use (&$count) { + $this->assertSame( + "find '/vendor/package/proofs/' '-type' 'f' | xargs '-n' '1' '-r' 'stat' '-f' '%Sm %N' '-t' '%Y-%m-%dT%H-%M-%S'", + $command->toString(), + ); + + $builder = Builder::foreground(2); + $builder = match ($count) { + 0 => $builder->success([['output', 'output']]), + 1 => $builder->success([['changed', 'output']]), + 2 => $builder->failed(), + }; + ++$count; + + return Attempt::result($builder->build()); + }, + )), ); $activities = Activities::new( diff --git a/tests/Agent/WatchPropertiesTest.php b/tests/Agent/WatchPropertiesTest.php index 1d1377d..b032e5a 100644 --- a/tests/Agent/WatchPropertiesTest.php +++ b/tests/Agent/WatchPropertiesTest.php @@ -16,13 +16,19 @@ OperatingSystem, Config, }; +use Innmind\Server\Control\{ + Server, + Server\Process\Builder, +}; use Innmind\Filesystem\{ Adapter, Directory, }; -use Innmind\FileWatch\Watch; use Innmind\Url\Path; -use Innmind\Immutable\Set; +use Innmind\Immutable\{ + Set, + Attempt, +}; use PHPUnit\Framework\TestCase; class WatchPropertiesTest extends TestCase @@ -44,10 +50,28 @@ public function testSendMessageWhenSourcesAreModified() ->add(Directory::named('properties')) ->unwrap(); + $count = 0; $os = OperatingSystem::new( Config::new() ->mountFilesystemVia(static fn() => Attempt::result($adapter)) - ->useFileWatch(Watch::via()), // todo simulate file change + ->useServerControl(Server::via( + function($command) use (&$count) { + $this->assertSame( + "find '/vendor/package/properties/' '-type' 'f' | xargs '-n' '1' '-r' 'stat' '-f' '%Sm %N' '-t' '%Y-%m-%dT%H-%M-%S'", + $command->toString(), + ); + + $builder = Builder::foreground(2); + $builder = match ($count) { + 0 => $builder->success([['output', 'output']]), + 1 => $builder->success([['changed', 'output']]), + 2 => $builder->failed(), + }; + ++$count; + + return Attempt::result($builder->build()); + }, + )), ); $activities = Activities::new( diff --git a/tests/Agent/WatchSourcesTest.php b/tests/Agent/WatchSourcesTest.php index b0292ac..0ce83b3 100644 --- a/tests/Agent/WatchSourcesTest.php +++ b/tests/Agent/WatchSourcesTest.php @@ -16,10 +16,19 @@ OperatingSystem, Config, }; -use Innmind\Filesystem\Adapter; -use Innmind\FileWatch\Watch; +use Innmind\Server\Control\{ + Server, + Server\Process\Builder, +}; +use Innmind\Filesystem\{ + Adapter, + Directory, +}; use Innmind\Url\Path; -use Innmind\Immutable\Set; +use Innmind\Immutable\{ + Set, + Attempt, +}; use PHPUnit\Framework\TestCase; class WatchSourcesTest extends TestCase @@ -36,10 +45,33 @@ public function testSendMessageWhenSourcesAreModified() { $agent = new WatchSources; + $adapter = Adapter::inMemory(); + $_ = $adapter + ->add(Directory::named('src')) + ->unwrap(); + + $count = 0; $os = OperatingSystem::new( Config::new() - ->mountFilesystemVia(static fn() => Attempt::result(Adapter::inMemory())) - ->useFileWatch(Watch::via()), // todo simulate file change + ->mountFilesystemVia(static fn() => Attempt::result($adapter)) + ->useServerControl(Server::via( + function($command) use (&$count) { + $this->assertSame( + "find '/vendor/package/src/' '-type' 'f' | xargs '-n' '1' '-r' 'stat' '-f' '%Sm %N' '-t' '%Y-%m-%dT%H-%M-%S'", + $command->toString(), + ); + + $builder = Builder::foreground(2); + $builder = match ($count) { + 0 => $builder->success([['output', 'output']]), + 1 => $builder->success([['changed', 'output']]), + 2 => $builder->failed(), + }; + ++$count; + + return Attempt::result($builder->build()); + }, + )), ); $activities = Activities::new( diff --git a/tests/Agent/WatchTestsTest.php b/tests/Agent/WatchTestsTest.php index ffbf693..6c3b2f1 100644 --- a/tests/Agent/WatchTestsTest.php +++ b/tests/Agent/WatchTestsTest.php @@ -16,10 +16,19 @@ OperatingSystem, Config, }; -use Innmind\Filesystem\Adapter; -use Innmind\FileWatch\Watch; +use Innmind\Server\Control\{ + Server, + Server\Process\Builder, +}; +use Innmind\Filesystem\{ + Adapter, + Directory, +}; use Innmind\Url\Path; -use Innmind\Immutable\Set; +use Innmind\Immutable\{ + Set, + Attempt, +}; use PHPUnit\Framework\TestCase; class WatchTestsTest extends TestCase @@ -36,10 +45,33 @@ public function testSendMessageWhenSourcesAreModified() { $agent = new WatchTests; + $adapter = Adapter::inMemory(); + $_ = $adapter + ->add(Directory::named('tests')) + ->unwrap(); + + $count = 0; $os = OperatingSystem::new( Config::new() - ->mountFilesystemVia(static fn() => Attempt::result(Adapter::inMemory())) - ->useFileWatch(Watch::via()), // todo simulate file change + ->mountFilesystemVia(static fn() => Attempt::result($adapter)) + ->useServerControl(Server::via( + function($command) use (&$count) { + $this->assertSame( + "find '/vendor/package/tests/' '-type' 'f' | xargs '-n' '1' '-r' 'stat' '-f' '%Sm %N' '-t' '%Y-%m-%dT%H-%M-%S'", + $command->toString(), + ); + + $builder = Builder::foreground(2); + $builder = match ($count) { + 0 => $builder->success([['output', 'output']]), + 1 => $builder->success([['changed', 'output']]), + 2 => $builder->failed(), + }; + ++$count; + + return Attempt::result($builder->build()); + }, + )), ); $activities = Activities::new( From 45fd7fbab96025c0a5a29782cb079c11d3f2c28a Mon Sep 17 00:00:00 2001 From: Baptiste Langlade Date: Sun, 22 Feb 2026 17:45:39 +0100 Subject: [PATCH 4/5] remove assertions on command as it changes depending the OS --- tests/Agent/WatchFixturesTest.php | 7 +------ tests/Agent/WatchProofsTest.php | 7 +------ tests/Agent/WatchPropertiesTest.php | 7 +------ tests/Agent/WatchSourcesTest.php | 7 +------ tests/Agent/WatchTestsTest.php | 7 +------ 5 files changed, 5 insertions(+), 30 deletions(-) diff --git a/tests/Agent/WatchFixturesTest.php b/tests/Agent/WatchFixturesTest.php index a4e30cf..e4e8b75 100644 --- a/tests/Agent/WatchFixturesTest.php +++ b/tests/Agent/WatchFixturesTest.php @@ -55,12 +55,7 @@ public function testSendMessageWhenFixturesAreModified() Config::new() ->mountFilesystemVia(static fn() => Attempt::result($adapter)) ->useServerControl(Server::via( - function($command) use (&$count) { - $this->assertSame( - "find '/vendor/package/fixtures/' '-type' 'f' | xargs '-n' '1' '-r' 'stat' '-f' '%Sm %N' '-t' '%Y-%m-%dT%H-%M-%S'", - $command->toString(), - ); - + static function($command) use (&$count) { $builder = Builder::foreground(2); $builder = match ($count) { 0 => $builder->success([['output', 'output']]), diff --git a/tests/Agent/WatchProofsTest.php b/tests/Agent/WatchProofsTest.php index 89d9efa..70d9601 100644 --- a/tests/Agent/WatchProofsTest.php +++ b/tests/Agent/WatchProofsTest.php @@ -55,12 +55,7 @@ public function testSendMessageWhenProofsAreModified() Config::new() ->mountFilesystemVia(static fn() => Attempt::result($adapter)) ->useServerControl(Server::via( - function($command) use (&$count) { - $this->assertSame( - "find '/vendor/package/proofs/' '-type' 'f' | xargs '-n' '1' '-r' 'stat' '-f' '%Sm %N' '-t' '%Y-%m-%dT%H-%M-%S'", - $command->toString(), - ); - + static function($command) use (&$count) { $builder = Builder::foreground(2); $builder = match ($count) { 0 => $builder->success([['output', 'output']]), diff --git a/tests/Agent/WatchPropertiesTest.php b/tests/Agent/WatchPropertiesTest.php index b032e5a..7451d65 100644 --- a/tests/Agent/WatchPropertiesTest.php +++ b/tests/Agent/WatchPropertiesTest.php @@ -55,12 +55,7 @@ public function testSendMessageWhenSourcesAreModified() Config::new() ->mountFilesystemVia(static fn() => Attempt::result($adapter)) ->useServerControl(Server::via( - function($command) use (&$count) { - $this->assertSame( - "find '/vendor/package/properties/' '-type' 'f' | xargs '-n' '1' '-r' 'stat' '-f' '%Sm %N' '-t' '%Y-%m-%dT%H-%M-%S'", - $command->toString(), - ); - + static function($command) use (&$count) { $builder = Builder::foreground(2); $builder = match ($count) { 0 => $builder->success([['output', 'output']]), diff --git a/tests/Agent/WatchSourcesTest.php b/tests/Agent/WatchSourcesTest.php index 0ce83b3..c14b258 100644 --- a/tests/Agent/WatchSourcesTest.php +++ b/tests/Agent/WatchSourcesTest.php @@ -55,12 +55,7 @@ public function testSendMessageWhenSourcesAreModified() Config::new() ->mountFilesystemVia(static fn() => Attempt::result($adapter)) ->useServerControl(Server::via( - function($command) use (&$count) { - $this->assertSame( - "find '/vendor/package/src/' '-type' 'f' | xargs '-n' '1' '-r' 'stat' '-f' '%Sm %N' '-t' '%Y-%m-%dT%H-%M-%S'", - $command->toString(), - ); - + static function($command) use (&$count) { $builder = Builder::foreground(2); $builder = match ($count) { 0 => $builder->success([['output', 'output']]), diff --git a/tests/Agent/WatchTestsTest.php b/tests/Agent/WatchTestsTest.php index 6c3b2f1..cade589 100644 --- a/tests/Agent/WatchTestsTest.php +++ b/tests/Agent/WatchTestsTest.php @@ -55,12 +55,7 @@ public function testSendMessageWhenSourcesAreModified() Config::new() ->mountFilesystemVia(static fn() => Attempt::result($adapter)) ->useServerControl(Server::via( - function($command) use (&$count) { - $this->assertSame( - "find '/vendor/package/tests/' '-type' 'f' | xargs '-n' '1' '-r' 'stat' '-f' '%Sm %N' '-t' '%Y-%m-%dT%H-%M-%S'", - $command->toString(), - ); - + static function($command) use (&$count) { $builder = Builder::foreground(2); $builder = match ($count) { 0 => $builder->success([['output', 'output']]), From f5fe590209793cf2914cc02df39781531c23d9db Mon Sep 17 00:00:00 2001 From: Baptiste Langlade Date: Sun, 22 Feb 2026 17:52:31 +0100 Subject: [PATCH 5/5] avoid using file watch with known bug --- composer.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/composer.json b/composer.json index e63e3b6..b5f735a 100644 --- a/composer.json +++ b/composer.json @@ -33,7 +33,8 @@ "phpunit/phpunit": "~10.2", "innmind/static-analysis": "~1.3", "innmind/black-box": "~6.5", - "innmind/coding-standard": "~2.0" + "innmind/coding-standard": "~2.0", + "innmind/file-watch": "^6.0.1" }, "bin": ["lab-station"] }