diff --git a/src/OutputFormatter/ConsoleOutputFormatter.php b/src/OutputFormatter/ConsoleOutputFormatter.php index db6de81d3..9528f64a6 100644 --- a/src/OutputFormatter/ConsoleOutputFormatter.php +++ b/src/OutputFormatter/ConsoleOutputFormatter.php @@ -4,6 +4,7 @@ namespace Qossmic\Deptrac\OutputFormatter; +use function count; use Qossmic\Deptrac\AstRunner\AstMap\FileOccurrence; use Qossmic\Deptrac\Console\Command\AnalyzeCommand; use Qossmic\Deptrac\Console\Output; @@ -57,6 +58,10 @@ public function finish( $this->printErrors($context, $output); } + if ($context->hasWarnings()) { + $this->printWarnings($context, $output); + } + $this->printSummary($context, $output); } @@ -104,10 +109,12 @@ private function printInheritPath(Output $output, InheritDependency $dependency) private function printSummary(Context $context, Output $output): void { - $violationCount = \count($context->violations()); - $skippedViolationCount = \count($context->skippedViolations()); - $uncoveredCount = \count($context->uncovered()); - $allowedCount = \count($context->allowed()); + $violationCount = count($context->violations()); + $skippedViolationCount = count($context->skippedViolations()); + $uncoveredCount = count($context->uncovered()); + $allowedCount = count($context->allowed()); + $warningsCount = count($context->warnings()); + $errorsCount = count($context->errors()); $output->writeLineFormatted(''); $output->writeLineFormatted('Report:'); @@ -133,6 +140,20 @@ private function printSummary(Context $context, Output $output): void ) ); $output->writeLineFormatted(sprintf('Allowed: %d', $allowedCount)); + $output->writeLineFormatted( + sprintf( + 'Warnings: %d', + $warningsCount > 0 ? 'yellow' : 'default', + $warningsCount + ) + ); + $output->writeLineFormatted( + sprintf( + 'Errors: %d', + $errorsCount > 0 ? 'red' : 'default', + $errorsCount + ) + ); } private function printUncovered(Context $context, Output $output): void @@ -173,4 +194,12 @@ private function printErrors(Context $context, Output $output): void $output->writeLineFormatted(sprintf('[ERROR] %s', $error->toString())); } } + + private function printWarnings(Context $context, Output $output): void + { + $output->writeLineFormatted(''); + foreach ($context->warnings() as $error) { + $output->writeLineFormatted(sprintf('[WARNING] %s', $error->toString())); + } + } } diff --git a/src/OutputFormatter/GithubActionsOutputFormatter.php b/src/OutputFormatter/GithubActionsOutputFormatter.php index dd67cdd41..61abc627c 100644 --- a/src/OutputFormatter/GithubActionsOutputFormatter.php +++ b/src/OutputFormatter/GithubActionsOutputFormatter.php @@ -88,6 +88,10 @@ public function finish(Context $context, Output $output, OutputFormatterInput $o if ($context->hasErrors()) { $this->printErrors($context, $output); } + + if ($context->hasWarnings()) { + $this->printWarnings($context, $output); + } } private function determineLogLevel(Rule $rule): string @@ -148,4 +152,11 @@ private function printErrors(Context $context, Output $output): void $output->writeLineFormatted('::error ::'.$error->toString()); } } + + private function printWarnings(Context $context, Output $output): void + { + foreach ($context->warnings() as $error) { + $output->writeLineFormatted('::warning ::'.$error->toString()); + } + } } diff --git a/src/OutputFormatter/TableOutputFormatter.php b/src/OutputFormatter/TableOutputFormatter.php index 8779a87fe..a85c024c1 100644 --- a/src/OutputFormatter/TableOutputFormatter.php +++ b/src/OutputFormatter/TableOutputFormatter.php @@ -4,6 +4,7 @@ namespace Qossmic\Deptrac\OutputFormatter; +use function count; use Qossmic\Deptrac\Console\Command\AnalyzeCommand; use Qossmic\Deptrac\Console\Output; use Qossmic\Deptrac\Dependency\InheritDependency; @@ -14,6 +15,7 @@ use Qossmic\Deptrac\RulesetEngine\SkippedViolation; use Qossmic\Deptrac\RulesetEngine\Uncovered; use Qossmic\Deptrac\RulesetEngine\Violation; +use Qossmic\Deptrac\RulesetEngine\Warning; use Symfony\Component\Console\Helper\TableSeparator; final class TableOutputFormatter implements OutputFormatterInterface @@ -73,6 +75,10 @@ public function finish( $this->printErrors($context, $output); } + if ($context->hasWarnings()) { + $this->printWarnings($context, $output); + } + $this->printSummary($context, $output); } @@ -123,10 +129,12 @@ private function formatInheritPath(InheritDependency $dependency): string private function printSummary(Context $context, Output $output): void { - $violationCount = \count($context->violations()); - $skippedViolationCount = \count($context->skippedViolations()); - $uncoveredCount = \count($context->uncovered()); - $allowedCount = \count($context->allowed()); + $violationCount = count($context->violations()); + $skippedViolationCount = count($context->skippedViolations()); + $uncoveredCount = count($context->uncovered()); + $allowedCount = count($context->allowed()); + $warningsCount = count($context->warnings()); + $errorsCount = count($context->errors()); $style = $output->getStyle(); $style->newLine(); @@ -136,7 +144,9 @@ private function printSummary(Context $context, Output $output): void ['Violations' => sprintf('%d', $violationCount > 0 ? 'red' : 'default', $violationCount)], ['Skipped violations' => sprintf('%d', $skippedViolationCount > 0 ? 'yellow' : 'default', $skippedViolationCount)], ['Uncovered' => sprintf('%d', $uncoveredCount > 0 ? 'yellow' : 'default', $uncoveredCount)], - ['Allowed' => $allowedCount] + ['Allowed' => $allowedCount], + ['Warnings' => sprintf('%d', $warningsCount > 0 ? 'yellow' : 'default', $warningsCount)], + ['Errors' => sprintf('%d', $errorsCount > 0 ? 'red' : 'default', $errorsCount)] ); } @@ -175,4 +185,17 @@ static function (Error $error) { ) ); } + + private function printWarnings(Context $context, Output $output): void + { + $output->getStyle()->table( + ['Warnings'], + array_map( + static function (Warning $warning) { + return [$warning->toString()]; + }, + $context->warnings() + ) + ); + } } diff --git a/src/RulesetEngine.php b/src/RulesetEngine.php index 07c656126..dfd55c25f 100644 --- a/src/RulesetEngine.php +++ b/src/RulesetEngine.php @@ -15,6 +15,7 @@ use Qossmic\Deptrac\RulesetEngine\SkippedViolationHelper; use Qossmic\Deptrac\RulesetEngine\Uncovered; use Qossmic\Deptrac\RulesetEngine\Violation; +use Qossmic\Deptrac\RulesetEngine\Warning; class RulesetEngine { @@ -24,6 +25,7 @@ public function process( Configuration $configuration ): Context { $rules = []; + $warnings = []; $configurationRuleset = $configuration->getRuleset(); $skippedViolationHelper = new SkippedViolationHelper($configuration->getSkipViolations()); @@ -31,6 +33,11 @@ public function process( foreach ($dependencyResult->getDependenciesAndInheritDependencies() as $dependency) { $layerNames = $classNameLayerResolver->getLayersByClassName($dependency->getClassLikeNameA()); + $classLikeANameString = $dependency->getClassLikeNameA()->toString(); + if (!isset($warnings[$classLikeANameString]) && count($layerNames) > 1) { + $warnings[$classLikeANameString] = Warning::classLikeIsInMoreThanOneLayer($dependency->getClassLikeNameA(), $layerNames); + } + foreach ($layerNames as $layerName) { $allowedDependencies = $configurationRuleset->getAllowedDependencies($layerName); @@ -70,7 +77,7 @@ public function process( } } - return new Context($rules, $errors); + return new Context($rules, $errors, $warnings); } private function ignoreUncoveredInternalClass(Configuration $configuration, ClassLikeName $classLikeName): bool diff --git a/src/RulesetEngine/Context.php b/src/RulesetEngine/Context.php index 79a360437..2bde72aa9 100644 --- a/src/RulesetEngine/Context.php +++ b/src/RulesetEngine/Context.php @@ -4,6 +4,9 @@ namespace Qossmic\Deptrac\RulesetEngine; +use function array_filter; +use function count; + final class Context { /** @@ -14,15 +17,21 @@ final class Context * @var Error[] */ private $errors; + /** + * @var Warning[] + */ + private $warnings; /** - * @param Rule[] $rules - * @param Error[] $errors + * @param Rule[] $rules + * @param Error[] $errors + * @param Warning[] $warnings */ - public function __construct(array $rules, array $errors) + public function __construct(array $rules, array $errors, array $warnings) { $this->rules = $rules; $this->errors = $errors; + $this->warnings = $warnings; } /** @@ -85,7 +94,7 @@ public function allowed(): array public function hasErrors(): bool { - return \count($this->errors) > 0; + return count($this->errors) > 0; } /** @@ -95,4 +104,17 @@ public function errors(): array { return $this->errors; } + + public function hasWarnings(): bool + { + return count($this->warnings) > 0; + } + + /** + * @return Warning[] + */ + public function warnings(): array + { + return $this->warnings; + } } diff --git a/src/RulesetEngine/Warning.php b/src/RulesetEngine/Warning.php new file mode 100644 index 000000000..fb3ae3d10 --- /dev/null +++ b/src/RulesetEngine/Warning.php @@ -0,0 +1,39 @@ +message = $message; + } + + /** + * @param string[] $layerNames + */ + public static function classLikeIsInMoreThanOneLayer( + ClassLikeName $getClassLikeNameA, + array $layerNames + ): self { + return new self(sprintf( + '%s is in more than one layer ["%s"]. It is recommended that one class should only be in one layer.', + $getClassLikeNameA->toString(), + implode('", "', $layerNames) + )); + } + + public function toString(): string + { + return $this->message; + } +} diff --git a/tests/OutputFormatter/BaselineOutputFormatterTest.php b/tests/OutputFormatter/BaselineOutputFormatterTest.php index 790f976ae..ddea6eb2d 100644 --- a/tests/OutputFormatter/BaselineOutputFormatterTest.php +++ b/tests/OutputFormatter/BaselineOutputFormatterTest.php @@ -105,7 +105,7 @@ public function testBasic(array $rules, string $expectedOutput): void $formatter = new BaselineOutputFormatter(); $formatter->finish( - new Context($rules, []), + new Context($rules, [], []), $this->createSymfonyOutput($output), new OutputFormatterInput(['baseline-dump' => $generatedBaselineFile]) ); diff --git a/tests/OutputFormatter/ConsoleOutputFormatterTest.php b/tests/OutputFormatter/ConsoleOutputFormatterTest.php index 50593c2ed..ba891e12a 100644 --- a/tests/OutputFormatter/ConsoleOutputFormatterTest.php +++ b/tests/OutputFormatter/ConsoleOutputFormatterTest.php @@ -20,6 +20,7 @@ use Qossmic\Deptrac\RulesetEngine\SkippedViolation; use Qossmic\Deptrac\RulesetEngine\Uncovered; use Qossmic\Deptrac\RulesetEngine\Violation; +use Qossmic\Deptrac\RulesetEngine\Warning; use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Output\BufferedOutput; use Symfony\Component\Console\Style\SymfonyStyle; @@ -55,6 +56,7 @@ public function basicDataProvider(): iterable ), ], [], + 'warnings' => [], ' ClassA must not depend on ClassB (LayerA on LayerB) originalA.php::12 @@ -69,6 +71,8 @@ public function basicDataProvider(): iterable Skipped violations: 0 Uncovered: 0 Allowed: 0 + Warnings:0 + Errors:0 ', ]; @@ -81,6 +85,7 @@ public function basicDataProvider(): iterable ), ], [], + 'warnings' => [], ' OriginalA must not depend on OriginalB (LayerA on LayerB) originalA.php::12 @@ -90,12 +95,15 @@ public function basicDataProvider(): iterable Skipped violations: 0 Uncovered: 0 Allowed: 0 + Warnings:0 + Errors:0 ', ]; yield [ [], [], + 'warnings' => [], ' Report: @@ -103,6 +111,8 @@ public function basicDataProvider(): iterable Skipped violations: 0 Uncovered: 0 Allowed: 0 + Warnings:0 + Errors:0 ', ]; @@ -115,6 +125,7 @@ public function basicDataProvider(): iterable ), ], [], + 'warnings' => [], '[SKIPPED] OriginalA must not depend on OriginalB (LayerA on LayerB) originalA.php::12 @@ -123,6 +134,8 @@ public function basicDataProvider(): iterable Skipped violations: 1 Uncovered: 0 Allowed: 0 + Warnings:0 + Errors:0 ', ]; @@ -134,6 +147,7 @@ public function basicDataProvider(): iterable ), ], [], + 'warnings' => [], ' Uncovered dependencies: OriginalA has uncovered dependency on OriginalB (LayerA) @@ -143,20 +157,30 @@ public function basicDataProvider(): iterable Skipped violations: 0 Uncovered: 1 Allowed: 0 + Warnings:0 + Errors:0 ', ]; yield 'an error occurred' => [ [], [new Error('an error occurred')], - '[ERROR]anerroroccurredReport:Violations:0Skippedviolations:0Uncovered:0Allowed:0', + 'warnings' => [], + '[ERROR]anerroroccurredReport:Violations:0Skippedviolations:0Uncovered:0Allowed:0Warnings:0Errors:1', + ]; + + yield 'an warning occurred' => [ + [], + [], + 'warnings' => [Warning::classLikeIsInMoreThanOneLayer(ClassLikeName::fromFQCN('Foo\Bar'), ['Layer 1', 'Layer 2'])], + '[WARNING]Foo\Barisinmorethanonelayer["Layer1","Layer2"].Itisrecommendedthatoneclassshouldonlybeinonelayer.Report:Violations:0Skippedviolations:0Uncovered:0Allowed:0Warnings:1Errors:0', ]; } /** * @dataProvider basicDataProvider */ - public function testBasic(array $rules, array $errors, string $expectedOutput): void + public function testBasic(array $rules, array $errors, array $warnings, string $expectedOutput): void { $bufferedOutput = new BufferedOutput(); $output = new SymfonyOutput( @@ -166,7 +190,7 @@ public function testBasic(array $rules, array $errors, string $expectedOutput): $formatter = new ConsoleOutputFormatter(); $formatter->finish( - new Context($rules, $errors), + new Context($rules, $errors, $warnings), $output, new OutputFormatterInput([ AnalyzeCommand::OPTION_REPORT_UNCOVERED => true, @@ -201,7 +225,7 @@ public function testWithoutSkippedViolations(): void $formatter = new ConsoleOutputFormatter(); $formatter->finish( - new Context($rules, []), + new Context($rules, [], []), $output, new OutputFormatterInput([ AnalyzeCommand::OPTION_REPORT_UNCOVERED => true, @@ -218,6 +242,8 @@ public function testWithoutSkippedViolations(): void Skipped violations: 1 Uncovered: 0 Allowed: 0 + Warnings:0 + Errors:0 '; self::assertEquals( diff --git a/tests/OutputFormatter/GithubActionsOutputFormatterTest.php b/tests/OutputFormatter/GithubActionsOutputFormatterTest.php index 03d348c45..4a2bba81d 100644 --- a/tests/OutputFormatter/GithubActionsOutputFormatterTest.php +++ b/tests/OutputFormatter/GithubActionsOutputFormatterTest.php @@ -20,6 +20,7 @@ use Qossmic\Deptrac\RulesetEngine\SkippedViolation; use Qossmic\Deptrac\RulesetEngine\Uncovered; use Qossmic\Deptrac\RulesetEngine\Violation; +use Qossmic\Deptrac\RulesetEngine\Warning; use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Output\BufferedOutput; use Symfony\Component\Console\Style\SymfonyStyle; @@ -35,13 +36,13 @@ public function testGetName() /** * @dataProvider finishProvider */ - public function testFinish(array $rules, array $errors, string $expectedOutput): void + public function testFinish(array $rules, array $errors, array $warnings, string $expectedOutput): void { $bufferedOutput = new BufferedOutput(); $formatter = new GithubActionsOutputFormatter(); $formatter->finish( - new Context($rules, $errors), + new Context($rules, $errors, $warnings), $this->createSymfonyOutput($bufferedOutput), new OutputFormatterInput([ AnalyzeCommand::OPTION_REPORT_UNCOVERED => true, @@ -55,8 +56,9 @@ public function testFinish(array $rules, array $errors, string $expectedOutput): public function finishProvider(): iterable { yield 'No Rules, No Output' => [ - [], - [], + 'rules' => [], + 'errors' => [], + 'warnings' => [], '', ]; @@ -65,42 +67,45 @@ public function finishProvider(): iterable $originalAOccurrence = FileOccurrence::fromFilepath('/home/testuser/originalA.php', 12); yield 'Simple Violation' => [ - [ + 'violations' => [ new Violation( new Dependency($originalA, $originalB, $originalAOccurrence), 'LayerA', 'LayerB' ), ], - [], + 'errors' => [], + 'warnings' => [], "::error file=/home/testuser/originalA.php,line=12::ACME\OriginalA must not depend on ACME\OriginalB (LayerA on LayerB)\n", ]; yield 'Skipped Violation' => [ - [ + 'violations' => [ new SkippedViolation( new Dependency($originalA, $originalB, $originalAOccurrence), 'LayerA', 'LayerB' ), ], - [], + 'errors' => [], + 'warnings' => [], "::warning file=/home/testuser/originalA.php,line=12::[SKIPPED] ACME\OriginalA must not depend on ACME\OriginalB (LayerA on LayerB)\n", ]; yield 'Uncovered Dependency' => [ - [ + 'violations' => [ new Uncovered( new Dependency($originalA, $originalB, $originalAOccurrence), 'LayerA' ), ], - [], + 'errors' => [], + 'warnings' => [], "::warning file=/home/testuser/originalA.php,line=12::ACME\OriginalA has uncovered dependency on ACME\OriginalB (LayerA)\n", ]; yield 'Inherit dependency' => [ - [ + 'violations' => [ new Violation( new InheritDependency( ClassLikeName::fromFQCN('ClassA'), @@ -117,15 +122,24 @@ public function finishProvider(): iterable 'LayerB' ), ], - [], + 'errors' => [], + 'warnings' => [], "::error file=originalA.php,line=12::ClassA must not depend on ClassB (LayerA on LayerB)%0AClassInheritD::6 ->%0AClassInheritC::5 ->%0AClassInheritB::4 ->%0AClassInheritA::3 ->%0AACME\OriginalB::12\n", ]; yield 'an error occurred' => [ - [], - [new Error('an error occurred')], + 'violations' => [], + 'errors' => [new Error('an error occurred')], + 'warnings' => [], "::error ::an error occurred\n", ]; + + yield 'an warning occurred' => [ + 'violations' => [], + 'errors' => [], + 'warnings' => [Warning::classLikeIsInMoreThanOneLayer(ClassLikeName::fromFQCN('Foo\Bar'), ['Layer 1', 'Layer 2'])], + "::warning ::Foo\Bar is in more than one layer [\"Layer 1\", \"Layer 2\"]. It is recommended that one class should only be in one layer.\n", + ]; } public function testWithoutSkippedViolations(): void @@ -146,7 +160,7 @@ public function testWithoutSkippedViolations(): void $formatter = new GithubActionsOutputFormatter(); $formatter->finish( - new Context($rules, []), + new Context($rules, [], []), $this->createSymfonyOutput($bufferedOutput), new OutputFormatterInput([ AnalyzeCommand::OPTION_REPORT_UNCOVERED => true, diff --git a/tests/OutputFormatter/GraphVizOutputFormatterTest.php b/tests/OutputFormatter/GraphVizOutputFormatterTest.php index 7d0faf9a9..f4401c116 100644 --- a/tests/OutputFormatter/GraphVizOutputFormatterTest.php +++ b/tests/OutputFormatter/GraphVizOutputFormatterTest.php @@ -39,7 +39,7 @@ public function testFinish(): void new Violation(new Dependency(ClassLikeName::fromFQCN('ClassAB'), ClassLikeName::fromFQCN('ClassBA'), FileOccurrence::fromFilepath('classAB.php', 1)), 'LayerA', 'LayerB'), new Allowed(new Dependency($classA, ClassLikeName::fromFQCN('ClassC'), $fileOccurrenceA), 'LayerA', 'LayerC'), new Uncovered(new Dependency($classA, ClassLikeName::fromFQCN('ClassD'), $fileOccurrenceA), 'LayerC'), - ], []); + ], [], []); $bufferedOutput = new BufferedOutput(); $input = new OutputFormatterInput([ diff --git a/tests/OutputFormatter/JUnitOutputFormatterTest.php b/tests/OutputFormatter/JUnitOutputFormatterTest.php index c16ad1723..c07cbbb22 100644 --- a/tests/OutputFormatter/JUnitOutputFormatterTest.php +++ b/tests/OutputFormatter/JUnitOutputFormatterTest.php @@ -124,7 +124,7 @@ public function testBasic(array $rules, string $expectedOutputFile): void { $formatter = new JUnitOutputFormatter(); $formatter->finish( - new Context($rules, []), + new Context($rules, [], []), $this->createSymfonyOutput(new BufferedOutput()), new OutputFormatterInput([ JUnitOutputFormatter::DUMP_XML => __DIR__.'/data/'.self::$actual_junit_report_file, diff --git a/tests/OutputFormatter/TableOutputFormatterTest.php b/tests/OutputFormatter/TableOutputFormatterTest.php index b4293532c..e2d7894bc 100644 --- a/tests/OutputFormatter/TableOutputFormatterTest.php +++ b/tests/OutputFormatter/TableOutputFormatterTest.php @@ -20,6 +20,7 @@ use Qossmic\Deptrac\RulesetEngine\SkippedViolation; use Qossmic\Deptrac\RulesetEngine\Uncovered; use Qossmic\Deptrac\RulesetEngine\Violation; +use Qossmic\Deptrac\RulesetEngine\Warning; use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Output\BufferedOutput; use Symfony\Component\Console\Style\SymfonyStyle; @@ -69,6 +70,7 @@ public function basicDataProvider(): iterable ), ], [], + 'warnings' => [], ' ----------- ------------------------------------------- Reason LayerA ----------- ------------------------------------------- @@ -89,6 +91,8 @@ public function basicDataProvider(): iterable Skipped violations 0 Uncovered 0 Allowed 0 + Warnings 0 + Errors 0 -------------------- ----- ', @@ -103,6 +107,7 @@ public function basicDataProvider(): iterable ), ], [], + 'warnings' => [], ' ----------- ------------------------------------------------- Reason LayerA ----------- ------------------------------------------------- @@ -118,6 +123,8 @@ public function basicDataProvider(): iterable Skipped violations 0 Uncovered 0 Allowed 0 + Warnings 0 + Errors 0 -------------------- ----- ', @@ -126,6 +133,7 @@ public function basicDataProvider(): iterable yield [ [], [], + 'warnings' => [], ' -------------------- ----- Report @@ -134,6 +142,8 @@ public function basicDataProvider(): iterable Skipped violations 0 Uncovered 0 Allowed 0 + Warnings 0 + Errors 0 -------------------- ----- ', @@ -148,6 +158,7 @@ public function basicDataProvider(): iterable ), ], [], + 'warnings' => [], ' --------- ------------------------------------------------- Reason LayerA --------- ------------------------------------------------- @@ -163,6 +174,8 @@ public function basicDataProvider(): iterable Skipped violations 1 Uncovered 0 Allowed 0 + Warnings 0 + Errors 0 -------------------- ----- ', @@ -177,6 +190,7 @@ public function basicDataProvider(): iterable ), ], [], + 'warnings' => [], ' -------------------- ----- Report @@ -185,6 +199,8 @@ public function basicDataProvider(): iterable Skipped violations 1 Uncovered 0 Allowed 0 + Warnings 0 + Errors 0 -------------------- ----- ', @@ -200,6 +216,7 @@ public function basicDataProvider(): iterable ), ], 'errors' => [], + 'warnings' => [], 'expectedOutput' => ' ----------- ------------------------------------------------- Reason LayerA ----------- ------------------------------------------------- @@ -215,6 +232,8 @@ public function basicDataProvider(): iterable Skipped violations 0 Uncovered 1 Allowed 0 + Warnings 0 + Errors 0 -------------------- ----- ', @@ -228,6 +247,7 @@ public function basicDataProvider(): iterable ), ], 'errors' => [], + 'warnings' => [], 'expectedOutput' => ' -------------------- ----- Report @@ -236,6 +256,8 @@ public function basicDataProvider(): iterable Skipped violations 0 Uncovered 1 Allowed 0 + Warnings 0 + Errors 0 -------------------- ----- ', @@ -245,6 +267,7 @@ public function basicDataProvider(): iterable yield 'an error occurred' => [ [], [new Error('an error occurred')], + 'warnings' => [], ' ------------------- Errors ------------------- @@ -259,6 +282,33 @@ public function basicDataProvider(): iterable Skipped violations 0 Uncovered 0 Allowed 0 + Warnings 0 + Errors 1 + -------------------- ----- + +', + ]; + + yield 'an warning occurred' => [ + 'rules' => [], + 'errors' => [], + 'warnings' => [Warning::classLikeIsInMoreThanOneLayer(ClassLikeName::fromFQCN('Foo\Bar'), ['Layer 1', 'Layer 2'])], + ' ------------------------------------------------------------------------------------------------------------------------- + Warnings + ------------------------------------------------------------------------------------------------------------------------- + Foo\Bar is in more than one layer ["Layer 1", "Layer 2"]. It is recommended that one class should only be in one layer. + ------------------------------------------------------------------------------------------------------------------------- + + + -------------------- ----- + Report + -------------------- ----- + Violations 0 + Skipped violations 0 + Uncovered 0 + Allowed 0 + Warnings 1 + Errors 0 -------------------- ----- ', @@ -268,7 +318,7 @@ public function basicDataProvider(): iterable /** * @dataProvider basicDataProvider */ - public function testBasic(array $rules, array $errors, string $expectedOutput, bool $reportUncovered = true, bool $reportSkipped = true): void + public function testBasic(array $rules, array $errors, array $warnings, string $expectedOutput, bool $reportUncovered = true, bool $reportSkipped = true): void { $bufferedOutput = new BufferedOutput(); $output = new SymfonyOutput( @@ -278,7 +328,7 @@ public function testBasic(array $rules, array $errors, string $expectedOutput, b $formatter = new TableOutputFormatter(); $formatter->finish( - new Context($rules, $errors), + new Context($rules, $errors, $warnings), $output, new OutputFormatterInput([ AnalyzeCommand::OPTION_REPORT_UNCOVERED => $reportUncovered, diff --git a/tests/OutputFormatter/XMLOutputFormatterTest.php b/tests/OutputFormatter/XMLOutputFormatterTest.php index 0ba78d0a7..746b290c9 100644 --- a/tests/OutputFormatter/XMLOutputFormatterTest.php +++ b/tests/OutputFormatter/XMLOutputFormatterTest.php @@ -120,7 +120,7 @@ public function testBasic(array $rules, $expectedOutputFile): void $formatter = new XMLOutputFormatter(); $formatter->finish( - new Context($rules, []), + new Context($rules, [], []), $this->createSymfonyOutput($bufferedOutput), new OutputFormatterInput([ XMLOutputFormatter::DUMP_XML => __DIR__.'/data/'.self::$actual_xml_report_file,