Skip to content

Commit

Permalink
fix: handle function definition cache invalidation when file is modified
Browse files Browse the repository at this point in the history
  • Loading branch information
romm committed Apr 6, 2022
1 parent 0b042bc commit 511a0df
Show file tree
Hide file tree
Showing 3 changed files with 54 additions and 4 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,14 @@
namespace CuyZ\Valinor\Definition\Repository\Cache\Compiler;

use CuyZ\Valinor\Cache\Compiled\CacheCompiler;
use CuyZ\Valinor\Cache\Compiled\CacheValidationCompiler;
use CuyZ\Valinor\Definition\FunctionDefinition;
use CuyZ\Valinor\Definition\ParameterDefinition;

use function var_export;

/** @internal */
final class FunctionDefinitionCompiler implements CacheCompiler
final class FunctionDefinitionCompiler implements CacheCompiler, CacheValidationCompiler
{
private TypeCompiler $typeCompiler;

Expand Down Expand Up @@ -48,4 +49,21 @@ public function compile($value): string
)
PHP;
}

public function compileValidation($value): string
{
assert($value instanceof FunctionDefinition);

$fileName = $value->fileName();

// If the file does not exist it means it's a native function so the
// definition is always valid.
if (null === $fileName) {
return 'true';
}

$time = filemtime($fileName);

return "\\filemtime('$fileName') === $time";
}
}
4 changes: 2 additions & 2 deletions tests/Fake/Definition/FakeFunctionDefinition.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,12 +13,12 @@

final class FakeFunctionDefinition
{
public static function new(): FunctionDefinition
public static function new(string $fileName = null): FunctionDefinition
{
return new FunctionDefinition(
'foo',
'foo:42-1337',
'foo/bar',
$fileName ?? 'foo/bar',
stdClass::class,
new Parameters(
new ParameterDefinition(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,15 @@
use CuyZ\Valinor\Definition\ParameterDefinition;
use CuyZ\Valinor\Definition\Parameters;
use CuyZ\Valinor\Definition\Repository\Cache\Compiler\FunctionDefinitionCompiler;
use CuyZ\Valinor\Tests\Fake\Definition\FakeFunctionDefinition;
use CuyZ\Valinor\Type\Types\NativeStringType;
use DateTime;
use Error;
use PHPUnit\Framework\TestCase;
use stdClass;

use function uniqid;

final class FunctionDefinitionCompilerTest extends TestCase
{
private FunctionDefinitionCompiler $compiler;
Expand Down Expand Up @@ -49,6 +53,7 @@ public function test_function_is_compiled_correctly(): void
$code = $this->compiler->compile($function);
$compiledFunction = $this->eval($code);

self::assertInstanceOf(FunctionDefinition::class, $compiledFunction);
self::assertSame('foo', $compiledFunction->name());
self::assertSame('foo:42-1337', $compiledFunction->signature());
self::assertSame('foo/bar', $compiledFunction->fileName());
Expand All @@ -57,7 +62,34 @@ public function test_function_is_compiled_correctly(): void
self::assertInstanceOf(NativeStringType::class, $compiledFunction->returnType());
}

private function eval(string $code): FunctionDefinition
public function test_modifying_function_definition_file_invalids_compiled_function_definition(): void
{
$fileName = sys_get_temp_dir() . DIRECTORY_SEPARATOR . uniqid() . ".php";

file_put_contents($fileName, "<?php function _valinor_test_modifying_function_definition_file_invalids_compiled_function_definition() {}");

include $fileName;

$class = FakeFunctionDefinition::new($fileName);

$validationCode = $this->compiler->compileValidation($class);
$firstValidation = $this->eval($validationCode);

unlink($fileName);
touch($fileName, (new DateTime('+5 seconds'))->getTimestamp());

$secondValidation = $this->eval($validationCode);

unlink($fileName);

self::assertTrue($firstValidation);
self::assertFalse($secondValidation);
}

/**
* @return FunctionDefinition|bool
*/
private function eval(string $code)
{
try {
return eval("return $code;");
Expand Down

0 comments on commit 511a0df

Please sign in to comment.