This repository has been archived on 2023-08-20. You can view files and clone it, but cannot push or open issues or pull requests.
symfony/tests/lib/vendor/lime/LimeAnnotationSupport.php
2010-01-04 15:26:20 +01:00

196 lines
4.7 KiB
PHP

<?php
/*
* This file is part of the Lime framework.
*
* (c) Fabien Potencier <fabien.potencier@symfony-project.com>
* (c) Bernhard Schussek <bernhard.schussek@symfony-project.com>
*
* This source file is subject to the MIT license that is bundled
* with this source code in the file LICENSE.
*/
/**
* Extends lime_test to support annotations in test files.
*
* With this extension of lime_test, you can write very simple test files that
* support more features than regular lime, such as code executed before
* or after each test, code executed before or after the whole test suite
* or expected exceptions.
*
* A test file can be written like this with LimeTest:
*
* <code>
* <?php
*
* include dirname(__FILE__).'/../bootstrap/unit.php';
*
* $t = new LimeTest(2, new lime_output_color());
*
* // @Before
* $r = new Record();
*
* // @Test
* $r->setValue('Bumblebee');
* $t->is($r->getValue(), 'Bumblebee', 'The setter works');
*
* // @Test
* $t->is($r->getValue(), 'Foobar', 'The value is "Foobar" by default');
* </code>
*
* The available annotations are:
*
* * @BeforeAll Executed before the whole test suite
* * @Before Executed before each test
* * @After Executed after each test
* * @AfterAll Executed after the whole test suite
* * @Test A test case
*
* You can add comments to the annotations that will be printed in the console:
*
* <code>
* // @Test: The record supports setValue()
* $r->setValue('Bumblebee')
* // etc.
* </code>
*
* You can also automatically test that certain exceptions are thrown from
* within a test. To do that, you must call the method ->expect() on the
* LimeTest object '''before''' executing the test that should throw
* an exception.
*
* <code>
* // @Test
* $r->expect('RuntimeException');
* throw new RuntimeException();
*
* // results in a passed test
* </code>
*
* @package lime
* @author Bernhard Schussek <bernhard.schussek@symfony-project.com>
* @version SVN: $Id: LimeAnnotationSupport.php 23701 2009-11-08 21:23:40Z bschussek $
*/
class LimeAnnotationSupport
{
protected static
$enabled = false;
protected
$originalPath = null,
$path = null,
$test = null,
$lexer = null;
/**
* Enables annotation support in a script file.
*/
public static function enable()
{
// make sure that annotations are not replaced twice at the same time
if (!self::$enabled)
{
self::$enabled = true;
$support = new LimeAnnotationSupport(self::getScriptPath());
$support->execute();
exit;
}
}
/**
* Returns the file path of the executed test script
*
* @return string The file path
*/
protected static function getScriptPath()
{
$traces = debug_backtrace();
$file = $traces[count($traces)-1]['file'];
if (!is_file($file))
{
throw new RuntimeException('The script name from the traces is not valid: '.$file);
}
return $file;
}
/**
* Constructor.
*
* Creates a backup of the given file with the extension .bak.
*/
protected function __construct($path)
{
$this->originalPath = $path;
$this->path = dirname($path).'/@'.basename($path);
register_shutdown_function(array($this, 'cleanup'));
}
/**
* Removes the transformed script file.
*/
public function cleanup()
{
if (file_exists($this->path))
{
unlink($this->path);
}
}
/**
* Transforms the annotations in the script file and executes the resulting
* script.
*/
protected function execute()
{
if (file_exists($this->path))
{
unlink($this->path);
}
$this->lexer = new LimeLexerTransformAnnotations($this->path);
$callbacks = $this->lexer->parse($this->originalPath);
$this->includeTestFile();
$testRunner = new LimeTestRunner($this->test ? $this->test->getOutput() : null);
foreach ($callbacks as $annotation => $callbacks)
{
$addMethod = 'add'.$annotation;
foreach ($callbacks as $list)
{
list ($callback, $comment) = $list;
$testRunner->$addMethod($callback, $comment);
}
}
if ($this->test instanceof LimeTest)
{
$testRunner->addExceptionHandler(array($this->test, 'handleException'));
$testRunner->addAfter(array($this->test, 'verifyException'));
}
$testRunner->run();
}
/**
* Includes the test file in a separate scope.
*
* @param string $testVariable
*/
protected function includeTestFile()
{
// var_dump(file_get_contents($this->path));
include $this->path;
if (!is_null($this->lexer->getTestVariable()))
{
eval(sprintf('$this->test = %s;', $this->lexer->getTestVariable()));
}
}
}