From b059a917c39a30972a25523e0667871616c0a465 Mon Sep 17 00:00:00 2001 From: Bellangelo Date: Sat, 28 Dec 2024 11:06:21 +0200 Subject: [PATCH 1/4] Create new value object for always asserting that a question option exist --- src/ComposerIntegration/MinimalHelperSet.php | 23 +++++++++++++ .../MinimalHelperSetTest.php | 33 +++++++++++++++++++ 2 files changed, 56 insertions(+) create mode 100644 src/ComposerIntegration/MinimalHelperSet.php create mode 100644 test/unit/ComposerIntegration/MinimalHelperSetTest.php diff --git a/src/ComposerIntegration/MinimalHelperSet.php b/src/ComposerIntegration/MinimalHelperSet.php new file mode 100644 index 00000000..38e1ad74 --- /dev/null +++ b/src/ComposerIntegration/MinimalHelperSet.php @@ -0,0 +1,23 @@ +expectNotToPerformAssertions(); + new MinimalHelperSet(['question' => $this->createMock(QuestionHelper::class)]); + } + + public function testQuestionOptionIsMissing(): void + { + $this->expectExceptionMessage('The question option must be an instance of Symfony\Component\Console\Helper\QuestionHelper, got NULL'); + new MinimalHelperSet([]); + } + + public function testQuestionOptionIsNotAQuestionHelper(): void + { + $this->expectExceptionMessage('The question option must be an instance of Symfony\Component\Console\Helper\QuestionHelper, got stdClass'); + new MinimalHelperSet(['question' => new stdClass()]); + } +} From bb38b70039acad76d8576c509d617558c507415a Mon Sep 17 00:00:00 2001 From: Bellangelo Date: Sat, 28 Dec 2024 11:07:12 +0200 Subject: [PATCH 2/4] Force QuieterConsoleIO to always require a question --- src/ComposerIntegration/QuieterConsoleIO.php | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/ComposerIntegration/QuieterConsoleIO.php b/src/ComposerIntegration/QuieterConsoleIO.php index dc75a79d..df191295 100644 --- a/src/ComposerIntegration/QuieterConsoleIO.php +++ b/src/ComposerIntegration/QuieterConsoleIO.php @@ -7,7 +7,6 @@ use Closure; use Composer\IO\ConsoleIO; use Composer\IO\IOInterface; -use Symfony\Component\Console\Helper\HelperSet; use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Output\OutputInterface; @@ -21,7 +20,7 @@ class QuieterConsoleIO extends ConsoleIO /** @var string[] */ public array $errors = []; - public function __construct(InputInterface $input, OutputInterface $output, HelperSet $helperSet) + public function __construct(InputInterface $input, OutputInterface $output, MinimalHelperSet $helperSet) { parent::__construct($input, $output, $helperSet); From a7c83284c3289d8ad89ff79eceb5b1ef49ad5376 Mon Sep 17 00:00:00 2001 From: Bellangelo Date: Sat, 28 Dec 2024 11:12:38 +0200 Subject: [PATCH 3/4] Update dependencies --- src/Container.php | 8 +++++++- test/unit/ComposerIntegration/QuieterConsoleIOTest.php | 10 +++++----- .../UnableToResolveRequirementTest.php | 6 +++--- 3 files changed, 15 insertions(+), 9 deletions(-) diff --git a/src/Container.php b/src/Container.php index 1c181a9a..4ac74d58 100644 --- a/src/Container.php +++ b/src/Container.php @@ -14,6 +14,7 @@ use Php\Pie\Command\InfoCommand; use Php\Pie\Command\InstallCommand; use Php\Pie\Command\ShowCommand; +use Php\Pie\ComposerIntegration\MinimalHelperSet; use Php\Pie\ComposerIntegration\QuieterConsoleIO; use Php\Pie\DependencyResolver\DependencyResolver; use Php\Pie\DependencyResolver\ResolveDependencyWithComposer; @@ -25,6 +26,7 @@ use Php\Pie\Installing\WindowsInstall; use Psr\Container\ContainerInterface; use Symfony\Component\Console\Helper\HelperSet; +use Symfony\Component\Console\Helper\QuestionHelper; use Symfony\Component\Console\Input\ArgvInput; use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Output\ConsoleOutput; @@ -50,7 +52,11 @@ public static function factory(): ContainerInterface return new QuieterConsoleIO( $container->get(InputInterface::class), $container->get(OutputInterface::class), - new HelperSet(), + new MinimalHelperSet( + [ + 'question' => new QuestionHelper(), + ], + ), ); }); diff --git a/test/unit/ComposerIntegration/QuieterConsoleIOTest.php b/test/unit/ComposerIntegration/QuieterConsoleIOTest.php index d94ac9fe..90769e87 100644 --- a/test/unit/ComposerIntegration/QuieterConsoleIOTest.php +++ b/test/unit/ComposerIntegration/QuieterConsoleIOTest.php @@ -5,11 +5,11 @@ namespace Php\PieUnitTest\ComposerIntegration; use Composer\IO\IOInterface; +use Php\Pie\ComposerIntegration\MinimalHelperSet; use Php\Pie\ComposerIntegration\QuieterConsoleIO; use PHPUnit\Framework\Attributes\CoversClass; use PHPUnit\Framework\Attributes\DataProvider; use PHPUnit\Framework\TestCase; -use Symfony\Component\Console\Helper\HelperSet; use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Output\Output; use Symfony\Component\Console\Output\OutputInterface; @@ -29,7 +29,7 @@ public function testErrorsAreLoggedAndWrittenWhenVerbose(): void ->method('write') ->with('Oh no'); - $io = new QuieterConsoleIO($symfonyInput, $symfonyOutput, new HelperSet([])); + $io = new QuieterConsoleIO($symfonyInput, $symfonyOutput, $this->createMock(MinimalHelperSet::class)); $io->writeError('Oh no'); self::assertSame(['Oh no'], $io->errors); @@ -47,7 +47,7 @@ public function testArrayOfErrorsAreLoggedAndWrittenWhenVerbose(): void ->method('write') ->with(['Oh no', 'Bad things']); - $io = new QuieterConsoleIO($symfonyInput, $symfonyOutput, new HelperSet([])); + $io = new QuieterConsoleIO($symfonyInput, $symfonyOutput, $this->createMock(MinimalHelperSet::class)); $io->writeError(['Oh no', 'Bad things']); self::assertSame(['Oh no', 'Bad things'], $io->errors); @@ -64,7 +64,7 @@ public function testErrorsAreLoggedButNotWritten(): void ->expects(self::never()) ->method('write'); - $io = new QuieterConsoleIO($symfonyInput, $symfonyOutput, new HelperSet([])); + $io = new QuieterConsoleIO($symfonyInput, $symfonyOutput, $this->createMock(MinimalHelperSet::class)); $io->writeError('Oh no'); self::assertSame(['Oh no'], $io->errors); @@ -105,7 +105,7 @@ protected function doWrite(string $message, bool $newline): void }; $symfonyOutput->setVerbosity($symfonyVerbosity); - $io = new QuieterConsoleIO($symfonyInput, $symfonyOutput, new HelperSet([])); + $io = new QuieterConsoleIO($symfonyInput, $symfonyOutput, $this->createMock(MinimalHelperSet::class)); $io->write('Quiet', verbosity: IOInterface::QUIET); $io->write('Normal', verbosity: IOInterface::NORMAL); diff --git a/test/unit/DependencyResolver/UnableToResolveRequirementTest.php b/test/unit/DependencyResolver/UnableToResolveRequirementTest.php index 5851ecff..7359a2f3 100644 --- a/test/unit/DependencyResolver/UnableToResolveRequirementTest.php +++ b/test/unit/DependencyResolver/UnableToResolveRequirementTest.php @@ -5,12 +5,12 @@ namespace Php\PieUnitTest\DependencyResolver; use Composer\Package\PackageInterface; +use Php\Pie\ComposerIntegration\MinimalHelperSet; use Php\Pie\ComposerIntegration\QuieterConsoleIO; use Php\Pie\DependencyResolver\RequestedPackageAndVersion; use Php\Pie\DependencyResolver\UnableToResolveRequirement; use PHPUnit\Framework\Attributes\CoversClass; use PHPUnit\Framework\TestCase; -use Symfony\Component\Console\Helper\HelperSet; use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Output\OutputInterface; @@ -42,7 +42,7 @@ public function testFromRequirementWithVersion(): void $io = new QuieterConsoleIO( $this->createMock(InputInterface::class), $this->createMock(OutputInterface::class), - $this->createMock(HelperSet::class), + $this->createMock(MinimalHelperSet::class), ); $io->writeError('message1'); $io->writeError('message2', true, QuieterConsoleIO::VERY_VERBOSE); @@ -58,7 +58,7 @@ public function testFromRequirementWithoutVersion(): void $io = new QuieterConsoleIO( $this->createMock(InputInterface::class), $this->createMock(OutputInterface::class), - $this->createMock(HelperSet::class), + $this->createMock(MinimalHelperSet::class), ); $io->writeError('message1'); $io->writeError('message2', true, QuieterConsoleIO::VERY_VERBOSE); From 2cf8af278899a440cffb1b44349d75b6f24df3da Mon Sep 17 00:00:00 2001 From: James Titcumb Date: Mon, 30 Dec 2024 09:25:13 +0000 Subject: [PATCH 4/4] Define type for MinimalHelperSet to eliminate some tests --- src/ComposerIntegration/MinimalHelperSet.php | 6 ++++-- src/Container.php | 1 - .../ComposerIntegration/MinimalHelperSetTest.php | 13 ------------- 3 files changed, 4 insertions(+), 16 deletions(-) diff --git a/src/ComposerIntegration/MinimalHelperSet.php b/src/ComposerIntegration/MinimalHelperSet.php index 38e1ad74..cda39161 100644 --- a/src/ComposerIntegration/MinimalHelperSet.php +++ b/src/ComposerIntegration/MinimalHelperSet.php @@ -8,14 +8,16 @@ use Symfony\Component\Console\Helper\QuestionHelper; use Webmozart\Assert\Assert; +/** @internal This is not public API for PIE, so should not be depended upon unless you accept the risk of BC breaks */ class MinimalHelperSet extends HelperSet { - public function __construct(array $helpers = []) + /** @param array{question: QuestionHelper} $helpers */ + public function __construct(array $helpers) { Assert::isInstanceOf( $helpers['question'] ?? null, QuestionHelper::class, - 'The question option must be an instance of %2$s, got %s' + 'The question option must be an instance of %2$s, got %s', ); parent::__construct($helpers); diff --git a/src/Container.php b/src/Container.php index 4ac74d58..28e1f885 100644 --- a/src/Container.php +++ b/src/Container.php @@ -25,7 +25,6 @@ use Php\Pie\Installing\UnixInstall; use Php\Pie\Installing\WindowsInstall; use Psr\Container\ContainerInterface; -use Symfony\Component\Console\Helper\HelperSet; use Symfony\Component\Console\Helper\QuestionHelper; use Symfony\Component\Console\Input\ArgvInput; use Symfony\Component\Console\Input\InputInterface; diff --git a/test/unit/ComposerIntegration/MinimalHelperSetTest.php b/test/unit/ComposerIntegration/MinimalHelperSetTest.php index 4b0313dc..d71e86d1 100644 --- a/test/unit/ComposerIntegration/MinimalHelperSetTest.php +++ b/test/unit/ComposerIntegration/MinimalHelperSetTest.php @@ -7,7 +7,6 @@ use Php\Pie\ComposerIntegration\MinimalHelperSet; use PHPUnit\Framework\Attributes\CoversClass; use PHPUnit\Framework\TestCase; -use stdClass; use Symfony\Component\Console\Helper\QuestionHelper; #[CoversClass(MinimalHelperSet::class)] @@ -18,16 +17,4 @@ public function testHappyPath(): void $this->expectNotToPerformAssertions(); new MinimalHelperSet(['question' => $this->createMock(QuestionHelper::class)]); } - - public function testQuestionOptionIsMissing(): void - { - $this->expectExceptionMessage('The question option must be an instance of Symfony\Component\Console\Helper\QuestionHelper, got NULL'); - new MinimalHelperSet([]); - } - - public function testQuestionOptionIsNotAQuestionHelper(): void - { - $this->expectExceptionMessage('The question option must be an instance of Symfony\Component\Console\Helper\QuestionHelper, got stdClass'); - new MinimalHelperSet(['question' => new stdClass()]); - } }