Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

"CLEAN" and "EXPECTREGEX" sections on PHPT files #1824

Closed
wants to merge 3 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
62 changes: 44 additions & 18 deletions src/Extensions/PhptTestCase.php
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,11 @@ class PHPUnit_Extensions_PhptTestCase implements PHPUnit_Framework_Test, PHPUnit
*/
private $filename;

/**
* @var PHPUnit_Util_PHP
*/
private $phpUtil;

/**
* @var array
*/
Expand Down Expand Up @@ -50,10 +55,12 @@ class PHPUnit_Extensions_PhptTestCase implements PHPUnit_Framework_Test, PHPUnit
/**
* Constructs a test case with the given filename.
*
* @param string $filename
* @param string $filename
* @param PHPUnit_Util_PHP $phpUtil
*
* @throws PHPUnit_Framework_Exception
*/
public function __construct($filename)
public function __construct($filename, $phpUtil = null)
{
if (!is_string($filename)) {
throw PHPUnit_Util_InvalidArgumentHelper::factory(1, 'string');
Expand All @@ -69,6 +76,7 @@ public function __construct($filename)
}

$this->filename = $filename;
$this->phpUtil = $phpUtil ?: PHPUnit_Util_PHP::factory();
}

/**
Expand All @@ -81,6 +89,31 @@ public function count()
return 1;
}

/**
* @param array $sections
* @param string $output
*/
private function assertPhptExpectation(array $sections, $output)
{
$assertions = array(
'EXPECT' => 'assertEquals',
'EXPECTF' => 'assertStringMatchesFormat',
'EXPECTREGEX' => 'assertRegExp',
);

$actual = preg_replace('/\r\n/', "\n", trim($output));
foreach ($assertions as $sectionName => $sectionAssertion) {
if (isset($sections[$sectionName])) {
$sectionContent = preg_replace('/\r\n/', "\n", trim($sections[$sectionName]));
$assertion = $sectionAssertion;
$expected = $sectionName == 'EXPECTREGEX' ? "/{$sectionContent}/" : $sectionContent;
break;
}
}

PHPUnit_Framework_Assert::$assertion($expected, $actual);
}

/**
* Runs a test and collects its result in a TestResult instance.
*
Expand All @@ -96,7 +129,6 @@ public function run(PHPUnit_Framework_TestResult $result = null)
$result = new PHPUnit_Framework_TestResult;
}

$php = PHPUnit_Util_PHP::factory();
$skip = false;
$time = 0;
$settings = $this->settings;
Expand All @@ -108,7 +140,7 @@ public function run(PHPUnit_Framework_TestResult $result = null)
}

if (isset($sections['SKIPIF'])) {
$jobResult = $php->runJob($sections['SKIPIF'], $settings);
$jobResult = $this->phpUtil->runJob($sections['SKIPIF'], $settings);

if (!strncasecmp('skip', ltrim($jobResult['stdout']), 4)) {
if (preg_match('/^\s*skip\s*(.+)\s*/i', $jobResult['stdout'], $message)) {
Expand All @@ -125,29 +157,23 @@ public function run(PHPUnit_Framework_TestResult $result = null)

if (!$skip) {
PHP_Timer::start();
$jobResult = $php->runJob($code, $settings);
$jobResult = $this->phpUtil->runJob($code, $settings);
$time = PHP_Timer::stop();

if (isset($sections['EXPECT'])) {
$assertion = 'assertEquals';
$expected = $sections['EXPECT'];
} else {
$assertion = 'assertStringMatchesFormat';
$expected = $sections['EXPECTF'];
}

$output = preg_replace('/\r\n/', "\n", trim($jobResult['stdout']));
$expected = preg_replace('/\r\n/', "\n", trim($expected));

try {
PHPUnit_Framework_Assert::$assertion($expected, $output);
$this->assertPhptExpectation($sections, $jobResult['stdout']);
} catch (PHPUnit_Framework_AssertionFailedError $e) {
$result->addFailure($this, $e, $time);
} catch (Throwable $t) {
$result->addError($this, $t, $time);
} catch (Exception $e) {
$result->addError($this, $e, $time);
}

if (isset($sections['CLEAN'])) {
$cleanCode = $this->render($sections['CLEAN']);
$this->phpUtil->runJob($cleanCode, $this->settings);
}
}

$result->endTest($this, $time);
Expand Down Expand Up @@ -197,7 +223,7 @@ private function parse()
}

if (!isset($sections['FILE']) ||
(!isset($sections['EXPECT']) && !isset($sections['EXPECTF']))) {
(!isset($sections['EXPECT']) && !isset($sections['EXPECTF']) && !isset($sections['EXPECTREGEX']))) {
throw new PHPUnit_Framework_Exception('Invalid PHPT file');
}

Expand Down
228 changes: 227 additions & 1 deletion tests/Extensions/PhptTestCaseTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,233 @@

class Extensions_PhptTestCaseTest extends \PHPUnit_Framework_TestCase
{
const EXPECT_CONTENT = <<<EOF
--TEST--
EXPECT test
--FILE--
<?php echo "Hello PHPUnit!"; ?>
--EXPECT--
Hello PHPUnit!
EOF;

const EXPECTF_CONTENT = <<<EOF
--TEST--
EXPECTF test
--FILE--
<?php echo "Hello PHPUnit!"; ?>
--EXPECTF--
Hello %s!
EOF;

const EXPECTREGEX_CONTENT = <<<EOF
--TEST--
EXPECTREGEX test
--FILE--
<?php echo "Hello PHPUnit!"; ?>
--EXPECTREGEX--
Hello [HPU]{4}[nit]{3}!
EOF;

const FILE_SECTION = <<<EOF
<?php echo "Hello PHPUnit!"; ?>

EOF;

protected $filename;
protected $testCase;
protected $phpUtil;

protected function setUp()
{
$this->filename = sys_get_temp_dir().'/phpunit.phpt';
touch($this->filename);

$this->phpUtil = $this->getMockForAbstractClass('PHPUnit_Util_PHP', [], '', false);

$this->testCase = new PHPUnit_Extensions_PhptTestCase($this->filename, $this->phpUtil);
}

protected function tearDown()
{
@unlink($this->filename);

$this->filename = null;
$this->testCase = null;
}

/**
* Defines the content of the current PHPT test.
*
* @param string $content
*/
private function setPhpContent($content)
{
file_put_contents($this->filename, $content);
}

public function testShouldRunFileSectionAsTest()
{
$this->setPhpContent(self::EXPECT_CONTENT);

$fileSection = '<?php echo "Hello PHPUnit!"; ?>'.PHP_EOL;

$this->phpUtil
->expects($this->once())
->method('runJob')
->with($fileSection)
->will($this->returnValue(['stdout' => '', 'stderr' => '']));

$this->testCase->run();
}

public function testShouldRunSkipifSectionWhenExists()
{
$skipifSection = '<?php /** Nothing **/ ?>'.PHP_EOL;

$phptContent = self::EXPECT_CONTENT.PHP_EOL;
$phptContent .= '--SKIPIF--'.PHP_EOL;
$phptContent .= $skipifSection;

$this->setPhpContent($phptContent);

$this->phpUtil
->expects($this->at(0))
->method('runJob')
->with($skipifSection)
->will($this->returnValue(['stdout' => '', 'stderr' => '']));

$this->testCase->run();
}

public function testShouldNotRunTestSectionIfSkipifSectionReturnsOutputWithSkipWord()
{
$skipifSection = '<?php echo "skip: Reason"; ?>'.PHP_EOL;

$phptContent = self::EXPECT_CONTENT.PHP_EOL;
$phptContent .= '--SKIPIF--'.PHP_EOL;
$phptContent .= $skipifSection;

$this->setPhpContent($phptContent);

$this->phpUtil
->expects($this->once())
->method('runJob')
->with($skipifSection)
->will($this->returnValue(['stdout' => 'skip: Reason', 'stderr' => '']));

$this->testCase->run();
}

public function testShouldRunCleanSectionWhenDefined()
{
$cleanSection = '<?php unlink("/tmp/something"); ?>' . PHP_EOL;

$phptContent = self::EXPECT_CONTENT . PHP_EOL;
$phptContent .= '--CLEAN--' . PHP_EOL;
$phptContent .= $cleanSection;

$this->setPhpContent($phptContent);

$this->phpUtil
->expects($this->at(1))
->method('runJob')
->with($cleanSection);

$this->testCase->run();
}

/**
* @expectedException PHPUnit_Framework_Exception
* @expectedExceptionMessage Invalid PHPT file
*/
public function testShouldThrowsAnExceptionWhenPhptFileIsEmpty()
{
$this->setPhpContent('');

$this->testCase->run();
}

/**
* @expectedException PHPUnit_Framework_Exception
* @expectedExceptionMessage Invalid PHPT file
*/
public function testShouldThrowsAnExceptionWhenFileSectionIsMissing()
{
$this->setPhpContent(
<<<EOF
--TEST--
Something to decribe it
--EXPECT--
Something
EOF
);
$this->testCase->run();
}

/**
* @expectedException PHPUnit_Framework_Exception
* @expectedExceptionMessage Invalid PHPT file
*/
public function testShouldThrowsAnExceptionWhenThereIsNoExpecOrExpectifOrExpecregexSectionInPhptFile()
{
$this->setPhpContent(
<<<EOF
--TEST--
Something to decribe it
--FILE--
<?php
echo "Hello world!\n";
?>
EOF
);
$this->testCase->run();
}

public function testShouldValidateExpectSession()
{
$this->setPhpContent(self::EXPECT_CONTENT);

$this->phpUtil
->expects($this->once())
->method('runJob')
->with(self::FILE_SECTION)
->will($this->returnValue(['stdout' => 'Hello PHPUnit!', 'stderr' => '']));

$result = $this->testCase->run();

$this->assertTrue($result->wasSuccessful());
}

public function testShouldValidateExpectfSession()
{
$this->setPhpContent(self::EXPECTF_CONTENT);

$this->phpUtil
->expects($this->once())
->method('runJob')
->with(self::FILE_SECTION)
->will($this->returnValue(['stdout' => 'Hello PHPUnit!', 'stderr' => '']));

$result = $this->testCase->run();

$this->assertTrue($result->wasSuccessful());
}

public function testShouldValidateExpectregexSession()
{
$this->setPhpContent(self::EXPECTREGEX_CONTENT);

$this->phpUtil
->expects($this->once())
->method('runJob')
->with(self::FILE_SECTION)
->will($this->returnValue(['stdout' => 'Hello PHPUnit!', 'stderr' => '']));

$result = $this->testCase->run();

$this->assertTrue($result->wasSuccessful());
}

public function testParseIniSection()
{
$phptTestCase = new PhpTestCaseProxy(__FILE__);
Expand All @@ -24,7 +251,6 @@ public function testParseIniSection()
];

$this->assertEquals($expected, $settings);

}
}

Expand Down