updateMethodSource(base_path($relativePath), $method); $restores = preg_match_all("/'status'\s*=>\s*\\\$previousStatus/", $body); $invalidations = substr_count($body, $invalidateCall); $this->assertGreaterThan(0, $restores, "{$relativePath} 에서 상태 복원 지점을 찾지 못했습니다 — 검사가 무력화됐습니다."); $this->assertGreaterThanOrEqual( $restores, $invalidations, "{$relativePath}: 상태 복원 {$restores}회에 비해 캐시 무효화가 {$invalidations}회뿐입니다 — " .'복원했는데 비우지 않은 경로가 있으면 그 확장 화면이 캐시 만료까지 404 로 남습니다.' ); } /** * 업데이트 메서드 본문을 주석 제거 후 반환합니다. * * 주석을 남겨 두면 설명 문장에 들어 있는 호출 표기가 검사를 통과시킨다. * * @param string $path 대상 파일 절대 경로 * @param string $method 대상 메서드명 (updateModule / updatePlugin) * @return string 주석이 제거된 메서드 본문 */ private function updateMethodSource(string $path, string $method): string { $this->assertFileExists($path); $stripped = ''; foreach (token_get_all(file_get_contents($path)) as $token) { if (is_array($token) && in_array($token[0], [T_COMMENT, T_DOC_COMMENT], true)) { continue; } $stripped .= is_array($token) ? $token[1] : $token; } $start = strpos($stripped, "public function {$method}("); $this->assertNotFalse($start, "{$path} 에서 {$method}() 메서드를 찾지 못했습니다."); // 중괄호 균형으로 메서드 본문 끝을 찾는다 $open = strpos($stripped, '{', $start); $depth = 0; $length = strlen($stripped); for ($i = $open; $i < $length; $i++) { if ($stripped[$i] === '{') { $depth++; } elseif ($stripped[$i] === '}') { $depth--; if ($depth === 0) { return substr($stripped, $open, $i - $open + 1); } } } $this->fail("{$path} 의 update() 본문 끝을 찾지 못했습니다."); } }