From d6918366e6a846a538d8ac2ea399a9e64da26dd0 Mon Sep 17 00:00:00 2001 From: Henrique Moody Date: Sat, 27 Dec 2014 11:25:03 -0200 Subject: [PATCH 1/3] Define PHPUnit_Util_PHP instance on PhptTestCase --- src/Extensions/PhptTestCase.php | 17 +++-- tests/Extensions/PhptTestCaseTest.php | 94 ++++++++++++++++++++++++++- 2 files changed, 105 insertions(+), 6 deletions(-) diff --git a/src/Extensions/PhptTestCase.php b/src/Extensions/PhptTestCase.php index afd9d66115a..49759afea31 100644 --- a/src/Extensions/PhptTestCase.php +++ b/src/Extensions/PhptTestCase.php @@ -20,6 +20,11 @@ class PHPUnit_Extensions_PhptTestCase implements PHPUnit_Framework_Test, PHPUnit */ private $filename; + /** + * @var PHPUnit_Util_PHP + */ + private $phpUtil; + /** * @var array */ @@ -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'); @@ -69,6 +76,7 @@ public function __construct($filename) } $this->filename = $filename; + $this->phpUtil = $phpUtil ?: PHPUnit_Util_PHP::factory(); } /** @@ -96,7 +104,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; @@ -108,7 +115,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)) { @@ -125,7 +132,7 @@ 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'])) { diff --git a/tests/Extensions/PhptTestCaseTest.php b/tests/Extensions/PhptTestCaseTest.php index 7c47068dc31..683c05c0019 100644 --- a/tests/Extensions/PhptTestCaseTest.php +++ b/tests/Extensions/PhptTestCaseTest.php @@ -10,6 +10,99 @@ class Extensions_PhptTestCaseTest extends \PHPUnit_Framework_TestCase { + const EXPECT_CONTENT = << +--EXPECT-- +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_EOL; + + $this->phpUtil + ->expects($this->once()) + ->method('runJob') + ->with($fileSection) + ->will($this->returnValue(['stdout' => '', 'stderr' => ''])); + + $this->testCase->run(); + } + + public function testShouldRunSkipifSectionWhenExists() + { + $skipifSection = ''.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_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(array('stdout' => 'skip: Reason', 'stderr' => ''))); + + $this->testCase->run(); + } + public function testParseIniSection() { $phptTestCase = new PhpTestCaseProxy(__FILE__); @@ -24,7 +117,6 @@ public function testParseIniSection() ]; $this->assertEquals($expected, $settings); - } } From d38ba690c484d4c78bcb93ec7dc127ba06464f83 Mon Sep 17 00:00:00 2001 From: Henrique Moody Date: Sat, 27 Dec 2014 11:47:29 -0200 Subject: [PATCH 2/3] Implement CLEAN section for PHPT test cases --- src/Extensions/PhptTestCase.php | 5 +++++ tests/Extensions/PhptTestCaseTest.php | 18 ++++++++++++++++++ 2 files changed, 23 insertions(+) diff --git a/src/Extensions/PhptTestCase.php b/src/Extensions/PhptTestCase.php index 49759afea31..c046f36f2d1 100644 --- a/src/Extensions/PhptTestCase.php +++ b/src/Extensions/PhptTestCase.php @@ -155,6 +155,11 @@ public function run(PHPUnit_Framework_TestResult $result = null) } 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); diff --git a/tests/Extensions/PhptTestCaseTest.php b/tests/Extensions/PhptTestCaseTest.php index 683c05c0019..1012cd40e9a 100644 --- a/tests/Extensions/PhptTestCaseTest.php +++ b/tests/Extensions/PhptTestCaseTest.php @@ -103,6 +103,24 @@ public function testShouldNotRunTestSectionIfSkipifSectionReturnsOutputWithSkipW $this->testCase->run(); } + public function testShouldRunCleanSectionWhenDefined() + { + $cleanSection = '' . 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(); + } + public function testParseIniSection() { $phptTestCase = new PhpTestCaseProxy(__FILE__); From 23debc3cb23b781e40aab26b244f7f55e4fd69a3 Mon Sep 17 00:00:00 2001 From: Henrique Moody Date: Sat, 27 Dec 2014 19:45:36 -0200 Subject: [PATCH 3/3] Implement EXPECTREGEX section for PHPT test cases --- src/Extensions/PhptTestCase.php | 40 ++++++--- tests/Extensions/PhptTestCaseTest.php | 118 +++++++++++++++++++++++++- 2 files changed, 144 insertions(+), 14 deletions(-) diff --git a/src/Extensions/PhptTestCase.php b/src/Extensions/PhptTestCase.php index c046f36f2d1..f2c7b57a6c2 100644 --- a/src/Extensions/PhptTestCase.php +++ b/src/Extensions/PhptTestCase.php @@ -89,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. * @@ -135,19 +160,8 @@ public function run(PHPUnit_Framework_TestResult $result = null) $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) { @@ -209,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'); } diff --git a/tests/Extensions/PhptTestCaseTest.php b/tests/Extensions/PhptTestCaseTest.php index 1012cd40e9a..ec26cb74a7e 100644 --- a/tests/Extensions/PhptTestCaseTest.php +++ b/tests/Extensions/PhptTestCaseTest.php @@ -18,6 +18,30 @@ class Extensions_PhptTestCaseTest extends \PHPUnit_Framework_TestCase --EXPECT-- Hello PHPUnit! EOF; + + const EXPECTF_CONTENT = << +--EXPECTF-- +Hello %s! +EOF; + + const EXPECTREGEX_CONTENT = << +--EXPECTREGEX-- +Hello [HPU]{4}[nit]{3}! +EOF; + + const FILE_SECTION = << + +EOF; + protected $filename; protected $testCase; protected $phpUtil; @@ -98,7 +122,7 @@ public function testShouldNotRunTestSectionIfSkipifSectionReturnsOutputWithSkipW ->expects($this->once()) ->method('runJob') ->with($skipifSection) - ->will($this->returnValue(array('stdout' => 'skip: Reason', 'stderr' => ''))); + ->will($this->returnValue(['stdout' => 'skip: Reason', 'stderr' => ''])); $this->testCase->run(); } @@ -121,6 +145,98 @@ public function testShouldRunCleanSectionWhenDefined() $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( +<<testCase->run(); + } + + /** + * @expectedException PHPUnit_Framework_Exception + * @expectedExceptionMessage Invalid PHPT file + */ + public function testShouldThrowsAnExceptionWhenThereIsNoExpecOrExpectifOrExpecregexSectionInPhptFile() + { + $this->setPhpContent( +<< +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__);