Skip to content

Commit

Permalink
TestHandler: initiateTestCase() caching (#378)
Browse files Browse the repository at this point in the history
  • Loading branch information
milo committed Jan 3, 2021
1 parent 1c843cf commit 43743fb
Show file tree
Hide file tree
Showing 2 changed files with 55 additions and 14 deletions.
1 change: 1 addition & 0 deletions src/Runner/Runner.php
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,7 @@ public function setTempDirectory(?string $path): void
}

$this->tempDir = $path;
$this->testHandler->setTempDirectory($path);
}


Expand Down
68 changes: 54 additions & 14 deletions src/Runner/TestHandler.php
Original file line number Diff line number Diff line change
Expand Up @@ -25,13 +25,22 @@ class TestHandler
/** @var Runner */
private $runner;

/** @var string|null */
private $tempDir;


public function __construct(Runner $runner)
{
$this->runner = $runner;
}


public function setTempDirectory(?string $path): void
{
$this->tempDir = $path;
}


public function initiate(string $file): void
{
[$annotations, $title] = $this->getAnnotations($file);
Expand Down Expand Up @@ -157,28 +166,59 @@ private function initiateMultiple(Test $test, $count): array

private function initiateTestCase(Test $test, $foo, PhpInterpreter $interpreter)
{
$job = new Job($test->withArguments(['method' => TestCase::LIST_METHODS]), $interpreter, $this->runner->getEnvironmentVariables());
$job->run();

if (in_array($job->getExitCode(), [Job::CODE_ERROR, Job::CODE_FAIL, Job::CODE_SKIP], true)) {
return $test->withResult($job->getExitCode() === Job::CODE_SKIP ? Test::SKIPPED : Test::FAILED, $job->getTest()->stdout);
$methods = null;

if ($this->tempDir) {
$cacheFile = $this->tempDir . DIRECTORY_SEPARATOR . 'TestHandler.testCase.' . substr(md5($test->getSignature()), 0, 5) . '.list';
if (is_file($cacheFile)) {
$cache = unserialize(file_get_contents($cacheFile));

$valid = true;
foreach ($cache['files'] as $path => $mTime) {
if (!is_file($path) || filemtime($path) !== $mTime) {
$valid = false;
break;
}
}
if ($valid) {
$methods = $cache['methods'];
}
}
}

$stdout = $job->getTest()->stdout;
if ($methods === null) {
$job = new Job($test->withArguments(['method' => TestCase::LIST_METHODS]), $interpreter, $this->runner->getEnvironmentVariables());
$job->run();

if (!preg_match('#^TestCase:([^\n]+)$#m', $stdout, $m)) {
return $test->withResult(Test::FAILED, "Cannot list TestCase methods in file '{$test->getFile()}'. Do you call TestCase::run() in it?");
}
$testCaseClass = $m[1];
if (in_array($job->getExitCode(), [Job::CODE_ERROR, Job::CODE_FAIL, Job::CODE_SKIP], true)) {
return $test->withResult($job->getExitCode() === Job::CODE_SKIP ? Test::SKIPPED : Test::FAILED, $job->getTest()->stdout);
}

$stdout = $job->getTest()->stdout;

preg_match_all('#^Method:([^\n]+)$#m', $stdout, $m);
if (count($m[1]) < 1) {
return $test->withResult(Test::SKIPPED, "Class $testCaseClass in file '{$test->getFile()}' does not contain test methods.");
if (!preg_match('#^TestCase:([^\n]+)$#m', $stdout, $m)) {
return $test->withResult(Test::FAILED, "Cannot list TestCase methods in file '{$test->getFile()}'. Do you call TestCase::run() in it?");
}
$testCaseClass = $m[1];

preg_match_all('#^Method:([^\n]+)$#m', $stdout, $m);
if (count($m[1]) < 1) {
return $test->withResult(Test::SKIPPED, "Class $testCaseClass in file '{$test->getFile()}' does not contain test methods.");
}
$methods = $m[1];

if ($this->tempDir) {
preg_match_all('#^Dependency:([^\n]+)$#m', $stdout, $m);
file_put_contents($cacheFile, serialize([
'methods' => $methods,
'files' => array_combine($m[1], array_map('filemtime', $m[1])),
]));
}
}

return array_map(function (string $method) use ($test): Test {
return $test->withArguments(['method' => $method]);
}, $m[1]);
}, $methods);
}


Expand Down

0 comments on commit 43743fb

Please sign in to comment.