diff --git a/tests/Agent/ARepairHintNamesACallTheHouseAdmitsTest.php b/tests/Agent/ARepairHintNamesACallTheHouseAdmitsTest.php index 82a38509..93c3e343 100644 --- a/tests/Agent/ARepairHintNamesACallTheHouseAdmitsTest.php +++ b/tests/Agent/ARepairHintNamesACallTheHouseAdmitsTest.php @@ -107,7 +107,7 @@ public function testTheCallAHintNamesIsOneTheHouseRuns(string $phase, string $su $rejection = $this->reject($house, $phase, $subject, $door); if ($rejection === null) { // Not every judge sees every subject: a test class is a judge, so nothing builds or runs it. - self::assertContains([$phase, $subject], [['container', 'test'], ['behavior', 'test']], "{$phase} did not reject a {$subject}"); + self::assertContains([$phase, $subject], [['container', 'test'], ['collaborators', 'test'], ['behavior', 'test']], "{$phase} did not reject a {$subject}"); return; } @@ -124,6 +124,11 @@ public function testTheCallAHintNamesIsOneTheHouseRuns(string $phase, string $su $followed = $house['door']->call('edit', ['plugin' => 'Blog', 'class' => $class, 'source' => ['session' => self::SESSION, 'seq' => $rejection['seq'], 'sha256' => $named[1]], 'edits' => $repair], $house['caller']); + } elseif (str_contains($hint, 'Make the edit this refusal writes out on the plugin class — a plain edit with find and replace, and no source')) { + // THE CURE IS NOT IN THE FILE (greenhouse evidence/1156): the hint names an edit of the PLUGIN class, a call + // of its own that lands first. That edit is the call the house has to run. + $followed = $house['door']->call('edit', ['plugin' => 'Blog', 'class' => 'Blog', + 'edits' => [['find' => self::BOOT, 'replace' => self::BOOT . ' the clock is registered here']]], $house['caller']); } elseif (preg_match('/complete corrected file with implement\b/', $hint) === 1) { $followed = $house['door']->call('implement', ['plugin' => 'Blog', 'class' => $class, 'content' => str_replace(self::defect($phase), self::REPAIRS[$phase], self::proposal($phase, $subject))], $house['caller']); @@ -162,10 +167,14 @@ public function testAHintForARecordedSourceIsWrittenOnlyWhenTheRecordedDoorAdmit 'edits' => [['find' => self::defect('container'), 'replace' => self::REPAIRS['container']]]], $terminal['caller']); } + /** The line of the plugin class a cure that is not in the file edits. */ + private const BOOT = '// boot:'; + private const REPAIRS = [ 'syntax' => 'public function index(): void {}', 'static-analysis' => '// conforms', 'container' => '// asks for nothing', + 'collaborators' => '// is handed what it works through', 'behavior' => '// does it', ]; @@ -240,6 +249,8 @@ private function house(array $scopes): array mkdir(\dirname($root . '/' . $path), 0o700, true); file_put_contents($root . '/' . $path, "temporary[] = $judges; mkdir($judges, 0o700); @@ -265,9 +276,14 @@ private function house(array $scopes): array [, , $root, $class] = $argv; $file = $root . '/src/Plugins/Blog/Controllers/' . substr((string) strrchr($class, '\\'), 1) . '.php'; $red = is_file($file) && str_contains((string) file_get_contents($file), '// RED:container'); + // What the probe says of an operation whose run() the house cannot hand what it works through (DevTools + // 0.44.2, greenhouse evidence/1154): the class is built, and the entry that lists it resolves nothing. + $unhanded = is_file($file) && str_contains((string) file_get_contents($file), '// RED:collaborators'); echo json_encode(['booted' => true, 'routes' => is_file($file) ? ['GET /blog'] : [], 'built' => !$red, 'error' => 'ContainerResolutionException: Cannot resolve parameter $container', - 'unresolvable' => [['parameter' => '$container', 'type' => 'Milpa\\Interfaces\\Di\\DIContainerInterface']]]), "\n"; + 'unresolvable' => [['parameter' => '$container', 'type' => 'Milpa\\Interfaces\\Di\\DIContainerInterface']]] + + ($unhanded ? ['operation' => ['name' => 'blog:posts', 'handed' => false, 'unhanded' => [ + ['type' => 'App\\Services\\Clock', 'error' => 'Service "App\\Services\\Clock" is not registered in the container.']]]] : [])), "\n"; PHP); chmod($judges . '/probe', 0o700); $runner = $judges . '/trial-run.php';