From 3f896bb36ec806c870d15feccd824d6486abdd95 Mon Sep 17 00:00:00 2001 From: William Allen Date: Fri, 9 Oct 2026 09:06:00 -0400 Subject: [PATCH] Use Laravel instead of legacy php-di Laravel's service provider provides all the DI functionality we need. This PR removes our legacy `php-di`-based service provider in favor of Laravel. --- .../Handlers/AbstractXmlHandler.php | 9 - app/Http/Submission/Handlers/BuildHandler.php | 17 +- .../Submission/Handlers/ConfigureHandler.php | 15 +- .../Handlers/DynamicAnalysisHandler.php | 15 +- .../Submission/Handlers/TestingHandler.php | 14 +- .../Submission/Handlers/UpdateHandler.php | 3 +- app/Utils/RepositoryUtils.php | 61 ----- app/cdash/app/Controller/Api/Timeline.php | 4 +- app/cdash/app/Model/Project.php | 14 +- app/cdash/include/CDash/ServiceContainer.php | 75 ------ .../CommitAuthorSubscriptionBuilder.php | 6 - app/cdash/include/Test/CDashTestCase.php | 7 - .../include/Test/CDashUseCaseTestCase.php | 176 +++++++------- app/cdash/include/common.php | 9 +- app/cdash/public/api/v1/buildgroup.php | 4 +- app/cdash/tests/CMakeLists.txt | 2 - .../tests/case/CDash/ServiceContainerTest.php | 78 ------ composer.json | 1 - composer.lock | 130 +--------- phpstan-baseline.neon | 226 +----------------- 20 files changed, 134 insertions(+), 732 deletions(-) delete mode 100644 app/cdash/include/CDash/ServiceContainer.php delete mode 100644 app/cdash/tests/case/CDash/ServiceContainerTest.php diff --git a/app/Http/Submission/Handlers/AbstractXmlHandler.php b/app/Http/Submission/Handlers/AbstractXmlHandler.php index 775749c790..01f672687d 100644 --- a/app/Http/Submission/Handlers/AbstractXmlHandler.php +++ b/app/Http/Submission/Handlers/AbstractXmlHandler.php @@ -21,7 +21,6 @@ use App\Utils\Stack; use CDash\Model\Build; use CDash\Model\Project; -use CDash\ServiceContainer; use DOMDocument; use Illuminate\Support\Facades\Storage; use League\Flysystem\UnableToReadFile; @@ -37,8 +36,6 @@ abstract class AbstractXmlHandler extends AbstractSubmissionHandler protected Site $Site; protected string $SubProjectName = ''; - private ServiceContainer $ModelFactory; - protected static ?string $schema_file = null; public function __construct(Build|Project $init) @@ -46,7 +43,6 @@ public function __construct(Build|Project $init) parent::__construct($init); $this->stack = new Stack(); - $this->ModelFactory = ServiceContainer::getInstance(); } /** @@ -184,11 +180,6 @@ public function getSubProjectName() return $this->Build->SubProjectName; } - protected function getModelFactory(): ServiceContainer - { - return $this->ModelFactory; - } - public function GetSite(): Site { return $this->Site; diff --git a/app/Http/Submission/Handlers/BuildHandler.php b/app/Http/Submission/Handlers/BuildHandler.php index 014fd2eca3..23f966b434 100644 --- a/app/Http/Submission/Handlers/BuildHandler.php +++ b/app/Http/Submission/Handlers/BuildHandler.php @@ -123,7 +123,6 @@ public function __construct(Project $project) public function startElement($parser, $name, $attributes): void { parent::startElement($parser, $name, $attributes); - $factory = $this->getModelFactory(); if ($this->currentPathMatches('site')) { $site_name = !empty($attributes['NAME']) ? $attributes['NAME'] : '(empty)'; @@ -182,7 +181,7 @@ public function startElement($parser, $name, $attributes): void $this->SubProjects[$this->SubProjectName] = []; } if (!array_key_exists($this->SubProjectName, $this->Builds)) { - $build = $factory->create(Build::class); + $build = app(Build::class); if (!empty($this->PullRequest)) { $build->SetPullRequest($this->PullRequest); } @@ -201,7 +200,7 @@ public function startElement($parser, $name, $attributes): void } elseif ($name === 'BUILD') { if (empty($this->Builds)) { // No subprojects - $build = $factory->create(Build::class); + $build = app(Build::class); if (!empty($this->PullRequest)) { $build->SetPullRequest($this->PullRequest); } @@ -218,15 +217,15 @@ public function startElement($parser, $name, $attributes): void $this->Builds[''] = $build; } } elseif ($name === 'WARNING') { - $this->Error = $factory->create(BuildError::class); + $this->Error = app(BuildError::class); $this->Error->Type = 1; $this->ErrorSubProjectName = ''; } elseif ($name === 'ERROR') { - $this->Error = $factory->create(BuildError::class); + $this->Error = app(BuildError::class); $this->Error->Type = 0; $this->ErrorSubProjectName = ''; } elseif ($name === 'FAILURE') { - $this->Error = $factory->create(BuildFailure::class); + $this->Error = app(BuildFailure::class); $this->Error->Type = 0; if ($attributes['TYPE'] === 'Error') { $this->Error->Type = 0; @@ -235,7 +234,7 @@ public function startElement($parser, $name, $attributes): void } $this->ErrorSubProjectName = ''; } elseif ($name === 'LABEL' && !$this->currentPathMatches('site.build.commands.*.labels.label')) { - $this->Label = $factory->create(Label::class); + $this->Label = app(Label::class); } elseif ($this->currentPathMatches('site.build.targets.target')) { if (array_key_exists($attributes['NAME'], $this->Targets)) { // In theory, this case should never happen... @@ -324,8 +323,6 @@ public function startElement($parser, $name, $attributes): void public function endElement($parser, $name): void { - $factory = $this->getModelFactory(); - if ($name === 'BUILD') { $start_time = gmdate(FMT_DATETIME, $this->StartTimeStamp); $end_time = gmdate(FMT_DATETIME, $this->EndTimeStamp); @@ -468,7 +465,7 @@ public function endElement($parser, $name): void } } if (!$hasLabel) { - $label = $factory->create(Label::class); + $label = app(Label::class); $label->text = $this->SubProjectName; if (!$this->Error instanceof BuildFailure) { throw new RuntimeException('Field "Error" is not instance of BuildFailure.'); diff --git a/app/Http/Submission/Handlers/ConfigureHandler.php b/app/Http/Submission/Handlers/ConfigureHandler.php index 390ffa1011..f07a699ae3 100644 --- a/app/Http/Submission/Handlers/ConfigureHandler.php +++ b/app/Http/Submission/Handlers/ConfigureHandler.php @@ -54,9 +54,6 @@ class ConfigureHandler extends AbstractXmlHandler implements ActionableBuildInte public function __construct(Project $project) { parent::__construct($project); - - // Instantiate model factory. - $this->getModelFactory(); } public function startElement($parser, $name, $attributes): void @@ -125,13 +122,13 @@ public function startElement($parser, $name, $attributes): void $this->Builds[$this->SubProjectName] = $build; } } elseif ($this->currentPathMatches('site.configure')) { - $this->Configure = $this->getModelFactory()->create(BuildConfigure::class); + $this->Configure = app(BuildConfigure::class); if (empty($this->Builds)) { // No subprojects $this->Builds[] = $this->CreateBuild(); } } elseif ($name === 'LABEL') { - $this->Label = $this->getModelFactory()->create(Label::class); + $this->Label = app(Label::class); } } @@ -182,7 +179,7 @@ public function endElement($parser, $name): void // Honor the Append flag if this build already existed. if ($this->Append) { // Get existing log & status from the database. - $existing_config = $this->getModelFactory()->create(BuildConfigure::class); + $existing_config = app(BuildConfigure::class); $existing_config->BuildId = $build->Id; if ($existing_config->Exists()) { $existing_config_results = $existing_config->GetConfigureForBuild(); @@ -225,7 +222,7 @@ public function endElement($parser, $name): void $duration = $this->EndTimeStamp - $this->StartTimeStamp; $build->SetConfigureDuration($duration, !$all_at_once); if ($all_at_once && !$parent_duration_set) { - $parent_build = $this->getModelFactory()->create(Build::class); + $parent_build = app(Build::class); $parent_build->Id = $build->GetParentId(); $parent_build->SetConfigureDuration($duration, false); $parent_duration_set = true; @@ -288,7 +285,7 @@ public function text($parser, $data): void } elseif ($parent === 'SUBPROJECT' && $element === 'LABEL') { $this->SubProjects[$this->SubProjectName][] = $data; $build = $this->Builds[$this->SubProjectName]; - $label = $this->getModelFactory()->create(Label::class); + $label = app(Label::class); $label->text = $data; $build->AddLabel($label); } elseif ($parent === 'LABELS' && $element === 'LABEL') { @@ -370,7 +367,7 @@ public function GetBuildGroup(): BuildGroup protected function CreateBuild() { - $build = $this->getModelFactory()->create(Build::class); + $build = app(Build::class); $build->SiteId = $this->Site->id; $build->Name = $this->BuildName; $build->SetStamp($this->BuildStamp); diff --git a/app/Http/Submission/Handlers/DynamicAnalysisHandler.php b/app/Http/Submission/Handlers/DynamicAnalysisHandler.php index 3a40c85944..2f91c3ee20 100644 --- a/app/Http/Submission/Handlers/DynamicAnalysisHandler.php +++ b/app/Http/Submission/Handlers/DynamicAnalysisHandler.php @@ -66,7 +66,6 @@ public function __construct(Project $project) public function startElement($parser, $name, $attributes): void { parent::startElement($parser, $name, $attributes); - $factory = $this->getModelFactory(); if ($this->currentPathMatches('site')) { $site_name = !empty($attributes['NAME']) ? $attributes['NAME'] : '(empty)'; @@ -121,7 +120,7 @@ public function startElement($parser, $name, $attributes): void } elseif ($name === 'DYNAMICANALYSIS') { $this->Checker = $attributes['CHECKER']; if (empty($this->DynamicAnalysisSummaries)) { - $summary = $factory->create(DynamicAnalysisSummary::class); + $summary = app(DynamicAnalysisSummary::class); $summary->Empty = true; $summary->Checker = $this->Checker; $this->DynamicAnalysisSummaries[$this->SubProjectName] = $summary; @@ -131,7 +130,7 @@ public function startElement($parser, $name, $attributes): void } } } elseif ($name === 'TEST' && isset($attributes['STATUS'])) { - $this->DynamicAnalysis = $factory->create(DynamicAnalysis::class); + $this->DynamicAnalysis = app(DynamicAnalysis::class); $this->DynamicAnalysis->Checker = $this->Checker; $this->DynamicAnalysis->Status = $attributes['STATUS']; $this->TestSubProjectName = ''; @@ -139,7 +138,7 @@ public function startElement($parser, $name, $attributes): void $this->DynamicAnalysisDefect = new DynamicAnalysisDefect(); $this->DynamicAnalysisDefect->type = $attributes['TYPE']; } elseif ($name === 'LABEL') { - $this->Label = $factory->create(Label::class); + $this->Label = app(Label::class); } elseif ($name === 'LOG') { $this->DynamicAnalysis->LogCompression = $attributes['COMPRESSION'] ?? ''; $this->DynamicAnalysis->LogEncoding = $attributes['ENCODING'] ?? ''; @@ -149,7 +148,6 @@ public function startElement($parser, $name, $attributes): void /** Function endElement */ public function endElement($parser, $name): void { - $factory = $this->getModelFactory(); if ($name === 'STARTTESTTIME' && $this->getParent() === 'DYNAMICANALYSIS') { if (empty($this->SubProjects)) { // Not a SubProject build. @@ -190,7 +188,7 @@ public function endElement($parser, $name): void // If everything is perfect CTest doesn't send any // But we still want a line showing the current dynamic analysis if ($this->DynamicAnalysisSummaries[$subprojectName]->Empty) { - $this->DynamicAnalysis = $factory->create(DynamicAnalysis::class); + $this->DynamicAnalysis = app(DynamicAnalysis::class); $this->DynamicAnalysis->BuildId = (int) $build->Id; $this->DynamicAnalysis->Status = 'passed'; $this->DynamicAnalysis->Checker = $this->Checker; @@ -278,8 +276,7 @@ public function getSubProjectName() private function createBuild($subprojectName): void { - $factory = $this->getModelFactory(); - $build = $factory->create(Build::class); + $build = app(Build::class); $build->SiteId = $this->Site->id; $build->Name = $this->BuildName; @@ -320,7 +317,7 @@ private function createBuild($subprojectName): void $this->Builds[$subprojectName] = $build; // Initialize a dynamic analysis summary for this build. - $summary = $factory->create(DynamicAnalysisSummary::class); + $summary = app(DynamicAnalysisSummary::class); $summary->Empty = true; $summary->BuildId = (int) $build->Id; $summary->Checker = $this->Checker; diff --git a/app/Http/Submission/Handlers/TestingHandler.php b/app/Http/Submission/Handlers/TestingHandler.php index 0a9dc31999..fb82b1daf9 100644 --- a/app/Http/Submission/Handlers/TestingHandler.php +++ b/app/Http/Submission/Handlers/TestingHandler.php @@ -69,7 +69,6 @@ public function __construct(Project $project) public function startElement($parser, $name, $attributes): void { parent::startElement($parser, $name, $attributes); - $factory = $this->getModelFactory(); if ($this->currentPathMatches('site')) { $site_name = !empty($attributes['NAME']) ? $attributes['NAME'] : '(empty)'; @@ -135,7 +134,7 @@ public function startElement($parser, $name, $attributes): void $this->TestSubProjectName = ''; $this->Labels = []; } elseif ($name === 'NAMEDMEASUREMENT' && array_key_exists('TYPE', $attributes)) { - $this->TestMeasurement = $factory->create(TestMeasurement::class); + $this->TestMeasurement = app(TestMeasurement::class); if ($attributes['TYPE'] === 'file') { $this->TestMeasurement->name = $attributes['FILENAME']; @@ -148,15 +147,13 @@ public function startElement($parser, $name, $attributes): void $this->TestCreator->alreadyCompressed = true; } } elseif ($name === 'LABEL' && $this->getParent() === 'LABELS') { - $this->Label = $factory->create(Label::class); + $this->Label = app(Label::class); } } /** End Element */ public function endElement($parser, $name): void { - $factory = $this->getModelFactory(); - if ($name === 'TEST' && $this->getParent() === 'TESTING') { // By now, will either have one subproject for the entire file // Or a subproject specifically for this test @@ -207,7 +204,7 @@ public function endElement($parser, $name): void // If it's an image we add it as an image if (str_contains($this->TestMeasurement->type, 'image')) { - $image = $factory->create(Image::class); + $image = app(Image::class); $image->Extension = $this->TestMeasurement->type; $image->Data = $this->TestMeasurement->value; $image->Name = $this->TestMeasurement->name; @@ -246,7 +243,7 @@ public function endElement($parser, $name): void $duration = $this->EndTimeStamp - $this->StartTimeStamp; $build->UpdateTestDuration($duration, !$all_at_once); if ($all_at_once && !$parent_duration_set) { - $parent_build = $factory->create(Build::class); + $parent_build = app(Build::class); $parent_build->Id = $build->GetParentId(); $parent_build->UpdateTestDuration($duration, false); $parent_duration_set = true; @@ -338,9 +335,8 @@ private function createBuild(): void if (!array_key_exists($this->SubProjectName, $this->NumberTestsPassed)) { $this->NumberTestsPassed[$this->SubProjectName] = 0; } - $factory = $this->getModelFactory(); /** @var Build $build */ - $build = $factory->create(Build::class); + $build = app(Build::class); $build->SetSite($this->Site); if (!empty($this->PullRequest)) { diff --git a/app/Http/Submission/Handlers/UpdateHandler.php b/app/Http/Submission/Handlers/UpdateHandler.php index ebe70e28f3..dea16d2628 100644 --- a/app/Http/Submission/Handlers/UpdateHandler.php +++ b/app/Http/Submission/Handlers/UpdateHandler.php @@ -57,10 +57,9 @@ public function __construct(Project $project) public function startElement($parser, $name, $attributes): void { parent::startElement($parser, $name, $attributes); - $factory = $this->getModelFactory(); if ($name === 'UPDATE') { $this->Build = new Build(); - $this->Update = $factory->create(BuildUpdate::class); + $this->Update = app(BuildUpdate::class); if (isset($attributes['GENERATOR'])) { $this->Build->Generator = $attributes['GENERATOR']; diff --git a/app/Utils/RepositoryUtils.php b/app/Utils/RepositoryUtils.php index 0caad6fb5a..535d7ae13c 100644 --- a/app/Utils/RepositoryUtils.php +++ b/app/Utils/RepositoryUtils.php @@ -8,7 +8,6 @@ use CDash\Database; use CDash\Model\Build; use CDash\Model\Project; -use CDash\ServiceContainer; use Illuminate\Support\Facades\Log; use Illuminate\Support\Str; use Illuminate\Support\Uri; @@ -35,66 +34,6 @@ public static function isGitHubUrl(string $url): bool return false; } - /** Return the GitHub diff URL */ - public static function get_github_diff_url($projecturl, $directory, $file, $revision) - { - if (empty($directory) && empty($file) && empty($revision)) { - return; - } - - // set a reasonable default revision if none was specified - if (empty($revision)) { - $revision = 'master'; - } - - $directory = trim($directory, '/'); - - $diff_url = "$projecturl/blob/$revision/"; - $diff_url .= "$directory/$file"; - return make_cdash_url($diff_url); - } - - /** Return the GitLab diff URL */ - public static function get_gitlab_diff_url($projecturl, $directory, $file, $revision): string - { - // Since GitLab supports arbitrarily nested groups, there is a `/-/` - // component to start per-project resources. - if ($revision !== '') { - $diff_url = $projecturl . '/-/commit/' . $revision; - } elseif ($file !== '') { - $diff_url = $projecturl . '/-/blob/master/'; - if ($directory !== '') { - $diff_url .= $directory . '/'; - } - $diff_url .= $file; - } else { - return ''; - } - return make_cdash_url($diff_url); - } - - /** Get the diff url based on the type of viewer */ - public static function get_diff_url($projectid, $projecturl, $directory, $file, $revision = '') - { - if (!is_numeric($projectid)) { - return; - } - - $service = ServiceContainer::getInstance(); - $project = $service->get(Project::class); - $project->Id = $projectid; - $project->Fill(); - - $cvsviewertype = strtolower($project->CvsViewerType ?? ''); - $difffunction = 'get_' . $cvsviewertype . '_diff_url'; - - if (method_exists(self::class, $difffunction)) { - return self::$difffunction($projecturl, $directory, $file, $revision); - } - // default is github - return self::get_github_diff_url($projecturl, $directory, $file, $revision); - } - /** Return the GitHub revision URL */ public static function get_github_revision_url($projecturl, $revision, $priorrevision): string { diff --git a/app/cdash/app/Controller/Api/Timeline.php b/app/cdash/app/Controller/Api/Timeline.php index 3afdd0c3c4..2c508c9b36 100644 --- a/app/cdash/app/Controller/Api/Timeline.php +++ b/app/cdash/app/Controller/Api/Timeline.php @@ -24,7 +24,6 @@ use CDash\Model\Build; use CDash\Model\BuildGroup; use CDash\Model\Project; -use CDash\ServiceContainer; use DateInterval; use DatePeriod; use DateTime; @@ -129,8 +128,7 @@ private function chartForTestOverview(): array private function chartForBuildGroup() { $groupname = urldecode(get_param('buildgroup')); - $service = ServiceContainer::getInstance(); - $buildgroup = $service->create(BuildGroup::class); + $buildgroup = new BuildGroup(); $buildgroup->SetProjectId($this->project->Id); $buildgroup->SetName($groupname); if (!$buildgroup->Exists()) { diff --git a/app/cdash/app/Model/Project.php b/app/cdash/app/Model/Project.php index 35aedd9061..076154c412 100644 --- a/app/cdash/app/Model/Project.php +++ b/app/cdash/app/Model/Project.php @@ -23,8 +23,6 @@ use CDash\Database; use CDash\Messaging\Notification\NotifyOn; use CDash\Messaging\Preferences\BitmaskNotificationPreferences; -use CDash\Messaging\Preferences\NotificationPreferences; -use CDash\ServiceContainer; use DateInterval; use DateTime; use DateTimeZone; @@ -554,8 +552,7 @@ public function SetSubscriberCollection(SubscriberCollection $subscribers): void */ protected function GetProjectSubscribers(): SubscriberCollection { - $service = ServiceContainer::getInstance()->getContainer(); - $collection = $service->make(SubscriberCollection::class); + $collection = new SubscriberCollection(); // TODO: works, but maybe find a better query $sql = ' SELECT @@ -572,11 +569,7 @@ protected function GetProjectSubscribers(): SubscriberCollection $user->execute(); foreach ($user->fetchAll(PDO::FETCH_OBJ) as $row) { - /** @var NotificationPreferences $preferences */ - $preferences = $service->make( - BitmaskNotificationPreferences::class, - ['mask' => $row->emailcategory] - ); + $preferences = new BitmaskNotificationPreferences($row->emailcategory); $preferences->setPreferencesFromEmailTypeProperty($row->emailtype); if ($preferences->get(NotifyOn::NEVER)) { continue; @@ -585,8 +578,7 @@ protected function GetProjectSubscribers(): SubscriberCollection $preferences->set(NotifyOn::SITE_MISSING, $row->emailmissingsites); $preferences->set(NotifyOn::REDUNDANT, $this->EmailRedundantFailures); - /** @var Subscriber $subscriber */ - $subscriber = $service->make(Subscriber::class, ['preferences' => $preferences]); + $subscriber = new Subscriber($preferences); $subscriber ->setAddress($row->email) ->setUserId($row->userid); diff --git a/app/cdash/include/CDash/ServiceContainer.php b/app/cdash/include/CDash/ServiceContainer.php deleted file mode 100644 index 8c03df9e1e..0000000000 --- a/app/cdash/include/CDash/ServiceContainer.php +++ /dev/null @@ -1,75 +0,0 @@ -container = $builder->build(); - } - - public static function container(): Container - { - return self::getInstance()->getContainer(); - } - - /** - * The create method will return a new instance of a class. - * - * @template T - * - * @param class-string $class_name - * - * @return T - */ - public function create(string $class_name) - { - return $this->container->make($class_name); - } - - /** - * The get method will return a singleton instance of a class. - * - * @template T - * - * @param class-string $class_name - * - * @return T - */ - public function get(string $class_name) - { - return $this->container->get($class_name); - } - - public function getContainer(): Container - { - return $this->container; - } - - public function setContainer(Container $container): void - { - $this->container = $container; - } -} diff --git a/app/cdash/include/Messaging/Subscription/CommitAuthorSubscriptionBuilder.php b/app/cdash/include/Messaging/Subscription/CommitAuthorSubscriptionBuilder.php index cfdfc12193..27c2d9942c 100644 --- a/app/cdash/include/Messaging/Subscription/CommitAuthorSubscriptionBuilder.php +++ b/app/cdash/include/Messaging/Subscription/CommitAuthorSubscriptionBuilder.php @@ -21,8 +21,6 @@ use CDash\Messaging\Notification\NotifyOn; use CDash\Messaging\Preferences\BitmaskNotificationPreferences; use CDash\Model\Subscriber; -use DI\DependencyException; -use DI\NotFoundException; /** * Class CommitAuthorSubscriptionBuilder @@ -48,10 +46,6 @@ public function __construct(ActionableBuildInterface $submission) $this->submission = $submission; } - /** - * @throws DependencyException - * @throws NotFoundException - */ public function build(SubscriptionCollection $subscriptions): void { $group = $this->submission->GetBuildGroup(); diff --git a/app/cdash/include/Test/CDashTestCase.php b/app/cdash/include/Test/CDashTestCase.php index 2bb034eba1..c4fced32f4 100644 --- a/app/cdash/include/Test/CDashTestCase.php +++ b/app/cdash/include/Test/CDashTestCase.php @@ -17,7 +17,6 @@ use CDash\Database; use CDash\Model\Build; -use CDash\ServiceContainer; use PDOStatement; use PHPUnit\Framework\MockObject\MockObject; use Tests\TestCase; @@ -29,12 +28,6 @@ class CDashTestCase extends TestCase /** @var Database */ private $originalDatabase; - public static function tearDownAfterClass(): void - { - ServiceContainer::setInstance(ServiceContainer::class, null); - parent::tearDownAfterClass(); - } - public function tearDown(): void { global $cdash_database_connection; diff --git a/app/cdash/include/Test/CDashUseCaseTestCase.php b/app/cdash/include/Test/CDashUseCaseTestCase.php index 95ac5e421e..0a78b80c40 100644 --- a/app/cdash/include/Test/CDashUseCaseTestCase.php +++ b/app/cdash/include/Test/CDashUseCaseTestCase.php @@ -2,105 +2,121 @@ namespace CDash\Test; +use App\Models\Label; +use App\Models\TestMeasurement; use CDash\Model\Build; -use CDash\ServiceContainer; +use CDash\Model\BuildConfigure; +use CDash\Model\BuildError; +use CDash\Model\BuildFailure; +use CDash\Model\BuildUpdate; +use CDash\Model\DynamicAnalysis; +use CDash\Model\DynamicAnalysisSummary; +use CDash\Model\Image; use CDash\Test\UseCase\UseCase; +use PHPUnit\Framework\MockObject\MockObject; class CDashUseCaseTestCase extends CDashTestCase { - /** @var ServiceContainer */ - private $originalServiceContainer; + /** + * The classes which the submission handlers resolve from the service container. Each of these + * is replaced with a mock when a use case is set up. Any class which the handlers resolve + * via app() but which is missing from this list will be instantiated for real instead. + */ + private const MOCKED_MODELS = [ + Build::class, + BuildConfigure::class, + BuildError::class, + BuildFailure::class, + BuildUpdate::class, + DynamicAnalysis::class, + DynamicAnalysisSummary::class, + Image::class, + Label::class, + TestMeasurement::class, + ]; - public function tearDown(): void + /** + * The bindings are registered on the container which app() resolves from rather than on + * $this->app, because some tests call createApplication() themselves, which replaces the global + * container instance. A fresh application is created for every test, so these bindings do not + * need to be removed when the test finishes. + */ + public function setUseCaseModelFactory(UseCase $useCase): void { - if ($this->originalServiceContainer) { - ServiceContainer::setInstance( - ServiceContainer::class, - $this->originalServiceContainer - ); + $this->setDatabaseMocked(); + + foreach (self::MOCKED_MODELS as $class_name) { + app()->bind($class_name, fn () => $this->makeUseCaseModelMock($class_name, $useCase)); } - parent::tearDown(); // TODO: Change the autogenerated stub } - public function setUseCaseModelFactory(UseCase $useCase): void + /** + * @param class-string $class_name + */ + private function makeUseCaseModelMock(string $class_name, UseCase $useCase): MockObject { - $this->setDatabaseMocked(); - $this->originalServiceContainer = ServiceContainer::getInstance(); + $methods = []; + foreach (['Insert', 'Update', 'Save', 'GetCommitAuthors', 'GetMissingTests'] as $method) { + if (method_exists($class_name, $method)) { + $methods[] = $method; + } + } - $mockServiceContainer = $this->getMockBuilder(ServiceContainer::class) - ->disableOriginalConstructor() - ->onlyMethods(['create']) + $model = $this->getMockBuilder($class_name) + ->onlyMethods($methods) ->getMock(); - $mockServiceContainer - ->expects($this->any()) - ->method('create') - ->willReturnCallback(function ($class_name) use ($useCase) { - $methods = []; - foreach (['Insert', 'Update', 'Save', 'GetCommitAuthors', 'GetMissingTests'] as $method) { - if (method_exists($class_name, $method)) { - $methods[] = $method; + if (method_exists($class_name, 'Save')) { + $model->expects($this->any()) + ->method('Save') + ->willReturnCallback(function () use ($class_name, $model, $useCase) { + $model->Id = $useCase->getIdForClass($class_name); + if (isset($model->Errors)) { + foreach ($model->Errors as $error) { + $error->BuildId = $model->Id; + } } - } - - $model = $this->getMockBuilder($class_name) - ->onlyMethods($methods) - ->getMock(); - - if (method_exists($class_name, 'Save')) { - $model->expects($this->any()) - ->method('Save') - ->willReturnCallback(function () use ($class_name, $model, $useCase) { - $model->Id = $useCase->getIdForClass($class_name); - if (isset($model->Errors)) { - foreach ($model->Errors as $error) { - $error->BuildId = $model->Id; - } - } - return $model->Id; - }); - } - - if (method_exists($class_name, 'Insert')) { - $model->expects($this->any()) - ->method('Insert') - ->willReturnCallback(function () use ($class_name, $model, $useCase) { - // TODO: discuss - if (!property_exists($model, 'Id')) { - $model->Id = null; - } + return $model->Id; + }); + } - if (!$model->Id) { - $model->Id = $useCase->getIdForClass($class_name); - } - return $model->Id; - }); - } + if (method_exists($class_name, 'Insert')) { + $model->expects($this->any()) + ->method('Insert') + ->willReturnCallback(function () use ($class_name, $model, $useCase) { + // TODO: discuss + if (!property_exists($model, 'Id')) { + $model->Id = null; + } - if (method_exists($class_name, 'GetCommitAuthors')) { - $model->expects($this->any()) - ->method('GetCommitAuthors') - ->willReturnCallback(function () use ($useCase, $model) { - /* @var Build|\PHPUnit\Framework\MockObject\MockObject $model */ - return $useCase->getAuthors($model->SubProjectName); - }); - } + if (!$model->Id) { + $model->Id = $useCase->getIdForClass($class_name); + } + return $model->Id; + }); + } - if (method_exists($class_name, 'GetMissingTests')) { - $model->expects($this->any()) - ->method('GetMissingTests') - ->willReturnCallback(function () use ($useCase) { - $missing = []; - if (isset($useCase->missingTests)) { - $missing = $useCase->missingTests; - } - return $missing; - }); - } + if (method_exists($class_name, 'GetCommitAuthors')) { + $model->expects($this->any()) + ->method('GetCommitAuthors') + ->willReturnCallback(function () use ($useCase, $model) { + /* @var Build|\PHPUnit\Framework\MockObject\MockObject $model */ + return $useCase->getAuthors($model->SubProjectName); + }); + } - return $model; - }); + if (method_exists($class_name, 'GetMissingTests')) { + $model->expects($this->any()) + ->method('GetMissingTests') + ->willReturnCallback(function () use ($useCase) { + $missing = []; + if (isset($useCase->missingTests)) { + $missing = $useCase->missingTests; + } + return $missing; + }); + } - ServiceContainer::setInstance(ServiceContainer::class, $mockServiceContainer); + return $model; } } diff --git a/app/cdash/include/common.php b/app/cdash/include/common.php index f8c1ee2bad..670d651021 100644 --- a/app/cdash/include/common.php +++ b/app/cdash/include/common.php @@ -32,7 +32,6 @@ use CDash\Database; use CDash\Model\Build; use CDash\Model\Project; -use CDash\ServiceContainer; use Illuminate\Auth\AuthenticationException; use Illuminate\Support\Facades\Auth; use Illuminate\Support\Facades\DB; @@ -386,8 +385,7 @@ function add_XML_value(string $tag, $value): string */ function get_project_id($projectname): int { - $service = ServiceContainer::getInstance(); - $project = $service->get(Project::class); + $project = new Project(); $project->Name = $projectname; if ($project->GetIdByName()) { return (int) $project->Id; @@ -566,10 +564,7 @@ function begin_JSON_response(): array */ function get_dashboard_JSON($projectname, $date, &$response): void { - $service = ServiceContainer::getInstance(); - - /** @var Project $project */ - $project = $service->create(Project::class); + $project = new Project(); $project->FindByName($projectname); $project_array = []; diff --git a/app/cdash/public/api/v1/buildgroup.php b/app/cdash/public/api/v1/buildgroup.php index 82140982cd..1adf9a63a3 100644 --- a/app/cdash/public/api/v1/buildgroup.php +++ b/app/cdash/public/api/v1/buildgroup.php @@ -23,7 +23,6 @@ use CDash\Model\BuildGroupRule; use App\Models\Site; use CDash\Model\Project; -use CDash\ServiceContainer; use Symfony\Component\HttpFoundation\Response; /** @@ -45,8 +44,7 @@ function just_get_project_from_request(): Project } $projectname = $_REQUEST['project']; $projectid = get_project_id($projectname); - $service = ServiceContainer::getInstance(); - $Project = $service->get(Project::class); + $Project = new Project(); $Project->Id = $projectid; if (!$Project->Exists()) { abort(404, 'Project does not exist'); diff --git a/app/cdash/tests/CMakeLists.txt b/app/cdash/tests/CMakeLists.txt index a175237008..36593cfb97 100644 --- a/app/cdash/tests/CMakeLists.txt +++ b/app/cdash/tests/CMakeLists.txt @@ -125,8 +125,6 @@ add_unit_test(/Unit/Utils/SubmissionUtilsTest) # TODO: Is this test useful now? add_legacy_unit_test(/PHPUnitTest) -add_legacy_unit_test(/CDash/ServiceContainer) - add_unit_test(/Unit/Console/Command/ValidateXmlCommandTest) add_unit_test(/Unit/GraphQL/SchemaValidationTest) diff --git a/app/cdash/tests/case/CDash/ServiceContainerTest.php b/app/cdash/tests/case/CDash/ServiceContainerTest.php deleted file mode 100644 index 91545b1392..0000000000 --- a/app/cdash/tests/case/CDash/ServiceContainerTest.php +++ /dev/null @@ -1,78 +0,0 @@ -assertInstanceOf(ServiceContainer::class, $instance); - } - - public function testSetInstance(): void - { - $mock_container = $this->getMockBuilder(ServiceContainer::class) - ->disableOriginalConstructor() - ->getMock(); - - ServiceContainer::setInstance(ServiceContainer::class, $mock_container); - $this->assertSame($mock_container, ServiceContainer::getInstance()); - } - - public function testCreate(): void - { - $mock_di = $this->getMockBuilder(Container::class) - ->disableOriginalConstructor() - ->onlyMethods(['make']) - ->getMock(); - - $mock_di - ->expects($this->once()) - ->method('make') - ->with($this->equalTo('SomeClassName')); - - $container = ServiceContainer::getInstance(); - $container->setContainer($mock_di); - $container->create('SomeClassName'); - } - - public function testGet(): void - { - $mock_di = $this->getMockBuilder(Container::class) - ->disableOriginalConstructor() - ->onlyMethods(['get']) - ->getMock(); - - $mock_di - ->expects($this->once()) - ->method('get') - ->with($this->equalTo('SomeClassName')); - - $container = ServiceContainer::getInstance(); - $container->setContainer($mock_di); - $container->get('SomeClassName'); - } -} diff --git a/composer.json b/composer.json index 39099abb21..9eedf0e1e6 100644 --- a/composer.json +++ b/composer.json @@ -35,7 +35,6 @@ "mll-lab/laravel-graphiql": "4.1.0", "nuwave/lighthouse": "6.70.1", "pear/archive_tar": "1.6.1", - "php-di/php-di": "7.1.1", "scaler-tech/laravel-saml2": "2.7.2", "sebastian/diff": "7.0.0", "socialiteproviders/github": "4.1.0", diff --git a/composer.lock b/composer.lock index c009f59a3d..d8c3ef244b 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "6e0c7568dabacf7efd4816e66ceeea2a", + "content-hash": "2fb3d8b75e96241304043c7d85681982", "packages": [ { "name": "aws/aws-crt-php", @@ -4003,134 +4003,6 @@ }, "time": "2021-03-21T15:43:46+00:00" }, - { - "name": "php-di/invoker", - "version": "2.3.7", - "source": { - "type": "git", - "url": "https://github.com/PHP-DI/Invoker.git", - "reference": "3c1ddfdef181431fbc4be83378f6d036d59e81e1" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/PHP-DI/Invoker/zipball/3c1ddfdef181431fbc4be83378f6d036d59e81e1", - "reference": "3c1ddfdef181431fbc4be83378f6d036d59e81e1", - "shasum": "" - }, - "require": { - "php": ">=7.3", - "psr/container": "^1.0|^2.0" - }, - "require-dev": { - "athletic/athletic": "~0.1.8", - "mnapoli/hard-mode": "~0.3.0", - "phpunit/phpunit": "^9.0 || ^10 || ^11 || ^12" - }, - "type": "library", - "autoload": { - "psr-4": { - "Invoker\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "description": "Generic and extensible callable invoker", - "homepage": "https://github.com/PHP-DI/Invoker", - "keywords": [ - "callable", - "dependency", - "dependency-injection", - "injection", - "invoke", - "invoker" - ], - "support": { - "issues": "https://github.com/PHP-DI/Invoker/issues", - "source": "https://github.com/PHP-DI/Invoker/tree/2.3.7" - }, - "funding": [ - { - "url": "https://github.com/mnapoli", - "type": "github" - } - ], - "time": "2025-08-30T10:22:22+00:00" - }, - { - "name": "php-di/php-di", - "version": "7.1.1", - "source": { - "type": "git", - "url": "https://github.com/PHP-DI/PHP-DI.git", - "reference": "f88054cc052e40dbe7b383c8817c19442d480352" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/PHP-DI/PHP-DI/zipball/f88054cc052e40dbe7b383c8817c19442d480352", - "reference": "f88054cc052e40dbe7b383c8817c19442d480352", - "shasum": "" - }, - "require": { - "laravel/serializable-closure": "^1.0 || ^2.0", - "php": ">=8.0", - "php-di/invoker": "^2.0", - "psr/container": "^1.1 || ^2.0" - }, - "provide": { - "psr/container-implementation": "^1.0" - }, - "require-dev": { - "friendsofphp/php-cs-fixer": "^3", - "friendsofphp/proxy-manager-lts": "^1", - "mnapoli/phpunit-easymock": "^1.3", - "phpunit/phpunit": "^9.6 || ^10 || ^11", - "vimeo/psalm": "^5|^6" - }, - "suggest": { - "friendsofphp/proxy-manager-lts": "Install it if you want to use lazy injection (version ^1)" - }, - "type": "library", - "autoload": { - "files": [ - "src/functions.php" - ], - "psr-4": { - "DI\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "description": "The dependency injection container for humans", - "homepage": "https://php-di.org/", - "keywords": [ - "PSR-11", - "container", - "container-interop", - "dependency injection", - "di", - "ioc", - "psr11" - ], - "support": { - "issues": "https://github.com/PHP-DI/PHP-DI/issues", - "source": "https://github.com/PHP-DI/PHP-DI/tree/7.1.1" - }, - "funding": [ - { - "url": "https://github.com/mnapoli", - "type": "github" - }, - { - "url": "https://tidelift.com/funding/github/packagist/php-di/php-di", - "type": "tidelift" - } - ], - "time": "2025-08-16T11:10:48+00:00" - }, { "name": "php-http/cache-plugin", "version": "2.1.0", diff --git a/phpstan-baseline.neon b/phpstan-baseline.neon index d465221ea3..729d22c6f8 100644 --- a/phpstan-baseline.neon +++ b/phpstan-baseline.neon @@ -5211,7 +5211,7 @@ parameters: - rawMessage: 'Construct empty() is not allowed. Use more strict comparison.' identifier: empty.notAllowed - count: 7 + count: 3 path: app/Utils/RepositoryUtils.php - @@ -5346,42 +5346,6 @@ parameters: count: 1 path: app/Utils/RepositoryUtils.php - - - rawMessage: 'Method App\Utils\RepositoryUtils::get_diff_url() has no return type specified.' - identifier: missingType.return - count: 1 - path: app/Utils/RepositoryUtils.php - - - - rawMessage: 'Method App\Utils\RepositoryUtils::get_diff_url() has parameter $directory with no type specified.' - identifier: missingType.parameter - count: 1 - path: app/Utils/RepositoryUtils.php - - - - rawMessage: 'Method App\Utils\RepositoryUtils::get_diff_url() has parameter $file with no type specified.' - identifier: missingType.parameter - count: 1 - path: app/Utils/RepositoryUtils.php - - - - rawMessage: 'Method App\Utils\RepositoryUtils::get_diff_url() has parameter $projectid with no type specified.' - identifier: missingType.parameter - count: 1 - path: app/Utils/RepositoryUtils.php - - - - rawMessage: 'Method App\Utils\RepositoryUtils::get_diff_url() has parameter $projecturl with no type specified.' - identifier: missingType.parameter - count: 1 - path: app/Utils/RepositoryUtils.php - - - - rawMessage: 'Method App\Utils\RepositoryUtils::get_diff_url() has parameter $revision with no type specified.' - identifier: missingType.parameter - count: 1 - path: app/Utils/RepositoryUtils.php - - rawMessage: 'Method App\Utils\RepositoryUtils::get_email_summary() has parameter $errorkey with no type specified.' identifier: missingType.parameter @@ -5394,36 +5358,6 @@ parameters: count: 1 path: app/Utils/RepositoryUtils.php - - - rawMessage: 'Method App\Utils\RepositoryUtils::get_github_diff_url() has no return type specified.' - identifier: missingType.return - count: 1 - path: app/Utils/RepositoryUtils.php - - - - rawMessage: 'Method App\Utils\RepositoryUtils::get_github_diff_url() has parameter $directory with no type specified.' - identifier: missingType.parameter - count: 1 - path: app/Utils/RepositoryUtils.php - - - - rawMessage: 'Method App\Utils\RepositoryUtils::get_github_diff_url() has parameter $file with no type specified.' - identifier: missingType.parameter - count: 1 - path: app/Utils/RepositoryUtils.php - - - - rawMessage: 'Method App\Utils\RepositoryUtils::get_github_diff_url() has parameter $projecturl with no type specified.' - identifier: missingType.parameter - count: 1 - path: app/Utils/RepositoryUtils.php - - - - rawMessage: 'Method App\Utils\RepositoryUtils::get_github_diff_url() has parameter $revision with no type specified.' - identifier: missingType.parameter - count: 1 - path: app/Utils/RepositoryUtils.php - - rawMessage: 'Method App\Utils\RepositoryUtils::get_github_revision_url() has parameter $priorrevision with no type specified.' identifier: missingType.parameter @@ -5442,30 +5376,6 @@ parameters: count: 1 path: app/Utils/RepositoryUtils.php - - - rawMessage: 'Method App\Utils\RepositoryUtils::get_gitlab_diff_url() has parameter $directory with no type specified.' - identifier: missingType.parameter - count: 1 - path: app/Utils/RepositoryUtils.php - - - - rawMessage: 'Method App\Utils\RepositoryUtils::get_gitlab_diff_url() has parameter $file with no type specified.' - identifier: missingType.parameter - count: 1 - path: app/Utils/RepositoryUtils.php - - - - rawMessage: 'Method App\Utils\RepositoryUtils::get_gitlab_diff_url() has parameter $projecturl with no type specified.' - identifier: missingType.parameter - count: 1 - path: app/Utils/RepositoryUtils.php - - - - rawMessage: 'Method App\Utils\RepositoryUtils::get_gitlab_diff_url() has parameter $revision with no type specified.' - identifier: missingType.parameter - count: 1 - path: app/Utils/RepositoryUtils.php - - rawMessage: 'Method App\Utils\RepositoryUtils::get_gitlab_revision_url() has parameter $priorrevision with no type specified.' identifier: missingType.parameter @@ -5661,7 +5571,7 @@ parameters: - rawMessage: Variable static method call on App\Utils\RepositoryUtils. identifier: staticMethod.dynamicName - count: 4 + count: 3 path: app/Utils/RepositoryUtils.php - @@ -9039,12 +8949,6 @@ parameters: count: 1 path: app/cdash/app/Model/Project.php - - - rawMessage: 'Cannot call method add() on mixed.' - identifier: method.nonObject - count: 1 - path: app/cdash/app/Model/Project.php - - rawMessage: 'Cannot call method bindParam() on PDOStatement|false.' identifier: method.nonObject @@ -9087,24 +8991,6 @@ parameters: count: 1 path: app/cdash/app/Model/Project.php - - - rawMessage: 'Method CDash\Model\Project::GetProjectSubscribers() should return CDash\Collection\SubscriberCollection but returns mixed.' - identifier: return.type - count: 1 - path: app/cdash/app/Model/Project.php - - - - rawMessage: 'Method CDash\Model\Project::GetProjectSubscribers() throws checked exception DI\DependencyException but it''s missing from the PHPDoc @throws tag.' - identifier: missingType.checkedException - count: 3 - path: app/cdash/app/Model/Project.php - - - - rawMessage: 'Method CDash\Model\Project::GetProjectSubscribers() throws checked exception DI\NotFoundException but it''s missing from the PHPDoc @throws tag.' - identifier: missingType.checkedException - count: 3 - path: app/cdash/app/Model/Project.php - - rawMessage: 'Method CDash\Model\Project::GetRepositories() return type has no value type specified in iterable type array.' identifier: missingType.iterableValue @@ -9579,30 +9465,6 @@ parameters: count: 2 path: app/cdash/include/CDash/Database.php - - - rawMessage: 'Method CDash\ServiceContainer::create() throws checked exception DI\DependencyException but it''s missing from the PHPDoc @throws tag.' - identifier: missingType.checkedException - count: 1 - path: app/cdash/include/CDash/ServiceContainer.php - - - - rawMessage: 'Method CDash\ServiceContainer::create() throws checked exception DI\NotFoundException but it''s missing from the PHPDoc @throws tag.' - identifier: missingType.checkedException - count: 1 - path: app/cdash/include/CDash/ServiceContainer.php - - - - rawMessage: 'Method CDash\ServiceContainer::get() throws checked exception DI\DependencyException but it''s missing from the PHPDoc @throws tag.' - identifier: missingType.checkedException - count: 1 - path: app/cdash/include/CDash/ServiceContainer.php - - - - rawMessage: 'Method CDash\ServiceContainer::get() throws checked exception DI\NotFoundException but it''s missing from the PHPDoc @throws tag.' - identifier: missingType.checkedException - count: 1 - path: app/cdash/include/CDash/ServiceContainer.php - - rawMessage: 'Method CDash\Singleton::__sleep() should return array but return statement is missing.' identifier: return.missing @@ -10713,24 +10575,12 @@ parameters: https://github.com/sebastianbergmann/phpunit/issues/6461 ''' identifier: method.deprecated - count: 5 - path: app/cdash/include/Test/CDashUseCaseTestCase.php - - - - rawMessage: 'Only booleans are allowed in an if condition, CDash\ServiceContainer given.' - identifier: if.condNotBoolean - count: 1 - path: app/cdash/include/Test/CDashUseCaseTestCase.php - - - - rawMessage: 'Parameter #1 $class_name of method CDash\Test\UseCase\UseCase::getIdForClass() expects string, class-string|object given.' - identifier: argument.type - count: 2 + count: 4 path: app/cdash/include/Test/CDashUseCaseTestCase.php - - rawMessage: 'Unable to resolve the template type T in call to method PHPUnit\Framework\TestCase::getMockBuilder()' - identifier: argument.templateType + rawMessage: 'Method CDash\Test\CDashUseCaseTestCase::setUseCaseModelFactory() throws checked exception TypeError but it''s missing from the PHPDoc @throws tag.' + identifier: missingType.checkedException count: 1 path: app/cdash/include/Test/CDashUseCaseTestCase.php @@ -13254,42 +13104,6 @@ parameters: count: 1 path: app/cdash/tests/case/CDash/Messaging/Subscription/CommitAuthorSubscriptionBuilderTest.php - - - rawMessage: 'Method CommitAuthorSubscriptionBuilderTest::testBuildGivenSubmissionWithBuildErrors() throws checked exception DI\DependencyException but it''s missing from the PHPDoc @throws tag.' - identifier: missingType.checkedException - count: 1 - path: app/cdash/tests/case/CDash/Messaging/Subscription/CommitAuthorSubscriptionBuilderTest.php - - - - rawMessage: 'Method CommitAuthorSubscriptionBuilderTest::testBuildGivenSubmissionWithBuildErrors() throws checked exception DI\NotFoundException but it''s missing from the PHPDoc @throws tag.' - identifier: missingType.checkedException - count: 1 - path: app/cdash/tests/case/CDash/Messaging/Subscription/CommitAuthorSubscriptionBuilderTest.php - - - - rawMessage: 'Method CommitAuthorSubscriptionBuilderTest::testBuildGivenSubmissionWithBuildWarnings() throws checked exception DI\DependencyException but it''s missing from the PHPDoc @throws tag.' - identifier: missingType.checkedException - count: 1 - path: app/cdash/tests/case/CDash/Messaging/Subscription/CommitAuthorSubscriptionBuilderTest.php - - - - rawMessage: 'Method CommitAuthorSubscriptionBuilderTest::testBuildGivenSubmissionWithBuildWarnings() throws checked exception DI\NotFoundException but it''s missing from the PHPDoc @throws tag.' - identifier: missingType.checkedException - count: 1 - path: app/cdash/tests/case/CDash/Messaging/Subscription/CommitAuthorSubscriptionBuilderTest.php - - - - rawMessage: 'Method CommitAuthorSubscriptionBuilderTest::testBuildGivenSubmissionWithTestFailures() throws checked exception DI\DependencyException but it''s missing from the PHPDoc @throws tag.' - identifier: missingType.checkedException - count: 1 - path: app/cdash/tests/case/CDash/Messaging/Subscription/CommitAuthorSubscriptionBuilderTest.php - - - - rawMessage: 'Method CommitAuthorSubscriptionBuilderTest::testBuildGivenSubmissionWithTestFailures() throws checked exception DI\NotFoundException but it''s missing from the PHPDoc @throws tag.' - identifier: missingType.checkedException - count: 1 - path: app/cdash/tests/case/CDash/Messaging/Subscription/CommitAuthorSubscriptionBuilderTest.php - - rawMessage: PHPDoc tag @var with type CDash\Model\Project is not subtype of native type PHPUnit\Framework\MockObject\MockObject. identifier: varTag.nativeType @@ -14022,36 +13836,6 @@ parameters: count: 1 path: app/cdash/tests/case/CDash/Service/RepositoryServiceTest.php - - - rawMessage: 'Call to method PHPUnit\Framework\Assert::assertInstanceOf() with ''CDash\\ServiceContainer'' and CDash\ServiceContainer will always evaluate to true.' - identifier: method.alreadyNarrowedType - count: 1 - path: app/cdash/tests/case/CDash/ServiceContainerTest.php - - - - rawMessage: 'Dynamic call to static method PHPUnit\Framework\Assert::equalTo().' - identifier: staticMethod.dynamicCall - count: 2 - path: app/cdash/tests/case/CDash/ServiceContainerTest.php - - - - rawMessage: 'Parameter #1 $class_name of method CDash\ServiceContainer::create() expects class-string, string given.' - identifier: argument.type - count: 1 - path: app/cdash/tests/case/CDash/ServiceContainerTest.php - - - - rawMessage: 'Parameter #1 $class_name of method CDash\ServiceContainer::get() expects class-string, string given.' - identifier: argument.type - count: 1 - path: app/cdash/tests/case/CDash/ServiceContainerTest.php - - - - rawMessage: Property ServiceContainerTest::$di has no type specified. - identifier: missingType.property - count: 1 - path: app/cdash/tests/case/CDash/ServiceContainerTest.php - - rawMessage: 'Call to an undefined method App\Http\Submission\Handlers\AbstractXmlHandler::GetBuildCollection().' identifier: method.notFound