Skip to content

Commit

Permalink
Add @testwith annotation support
Browse files Browse the repository at this point in the history
  • Loading branch information
farafiri committed Jun 23, 2014
1 parent 56f8daf commit bf1c416
Show file tree
Hide file tree
Showing 2 changed files with 189 additions and 0 deletions.
62 changes: 62 additions & 0 deletions src/Util/Test.php
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@ function trait_exists($traitname, $autoload = true)
class PHPUnit_Util_Test
{
const REGEX_DATA_PROVIDER = '/@dataProvider\s+([a-zA-Z0-9._:-\\\\x7f-\xff]+)/';
const REGEX_TEST_WITH = '/@testWith\s+/';
const REGEX_EXPECTED_EXCEPTION = '(@expectedException\s+([:.\w\\\\x7f-\xff]+)(?:[\t ]+(\S*))?(?:[\t ]+(\S*))?\s*$)m';
const REGEX_REQUIRES_VERSION = '/@requires\s+(?P<name>PHP(?:Unit)?)\s+(?P<value>[\d\.-]+(dev|(RC|alpha|beta)[\d\.])?)[ \t]*\r?$/m';
const REGEX_REQUIRES_OS = '/@requires\s+OS\s+(?P<value>.+?)[ \t]*\r?$/m';
Expand Down Expand Up @@ -435,6 +436,67 @@ public static function getProvidedData($className, $methodName)
return $data;
}

/**
* @param string $docComment full docComment string
* @return array when @testWith annotation is defined
* null when @testWith annotation is omitted
* @throws PHPUnit_Framework_Exception when @testWith annotation is defined but cannot be parsed
*/
public static function getDataFromTestWithAnnotation($docComment)
{
//removing initial ' * ' for docComment
$docComment = preg_replace('/\n\s*\*\s?/', "\n", $docComment);
if (preg_match(self::REGEX_TEST_WITH, $docComment, $matches, PREG_OFFSET_CAPTURE)) {
$offset = strlen($matches[0][0]) + $matches[0][1];
$nestLvl = 0;
$maxOffset = strlen($docComment);
$stringStop = false;
$outputStr = '';
$jsonEscape = array("\t" => '\t', "\n" => '\n', "\r" => '\r');
while ($offset < $maxOffset) {
$currentCharacter = substr($docComment, $offset, 1);
if ($stringStop) {
if ($currentCharacter === $stringStop) {
$stringStop = false;
$outputStr .= '"';
} elseif ($currentCharacter === '\\') {
$outputStr .= $currentCharacter . $docComment[$offset + 1];
$offset++;
} elseif(isset($jsonEscape[$currentCharacter])) {
$outputStr .= $jsonEscape[$currentCharacter];
} else {
$outputStr .= $currentCharacter;
}
} else {
if ($currentCharacter === '"' || $currentCharacter === "'") {
$stringStop = $currentCharacter;
$outputStr .= '"';
} elseif ($currentCharacter === '(') {
$outputStr .= ($outputStr ? ',' : '') . '[';
$nestLvl++;
} elseif ($currentCharacter === ')') {
$outputStr .= ']';
$nestLvl--;
} elseif (!preg_match('/\s/', $currentCharacter) && $nestLvl === 0) {
break;
} else {
$outputStr .= $currentCharacter;
}
}
$offset++;
}

$data = json_decode('[' . $outputStr . ']', true);
if ($data === null) {
throw new PHPUnit_Framework_Exception('Data set in invalid');
}

return $data;
}

return null;
}

/**
* @param string $className
* @param string $methodName
Expand Down
127 changes: 127 additions & 0 deletions tests/Util/TestTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -272,6 +272,133 @@ public function testGetProvidedDataRegEx()
$this->assertEquals('メソッド', $matches[1]);
}

/**
* @covers PHPUnit_Util_Test::getDataFromTestWithAnnotation
*/
public function testTestWithEmptyAnnotation()
{
$result = PHPUnit_Util_Test::getDataFromTestWithAnnotation("/**\n * @anotherAnnotation\n */");
$this->assertNull($result);
}

/**
* @covers PHPUnit_Util_Test::getDataFromTestWithAnnotation
*/
public function testTestWithSimpleCase()
{
$result = PHPUnit_Util_Test::getDataFromTestWithAnnotation("/**
* @testWith (1)
*/");
$this->assertEquals(array(array(1)), $result);
}

/**
* @covers PHPUnit_Util_Test::getDataFromTestWithAnnotation
*/
public function testTestWithMultiLineMultiParameterCase()
{
$result = PHPUnit_Util_Test::getDataFromTestWithAnnotation("/**
* @testWith (1, 2)
* (3, 4)
*/");
$this->assertEquals(array(array(1, 2), array(3, 4)), $result);
}

/**
* @covers PHPUnit_Util_Test::getDataFromTestWithAnnotation
*/
public function testTestWithMultiCaseInSingleLine()
{
$result = PHPUnit_Util_Test::getDataFromTestWithAnnotation("/**
* @testWith (1) (2) (3)
*/");
$this->assertEquals(array(array(1), array(2), array(3)), $result);
}

/**
* @covers PHPUnit_Util_Test::getDataFromTestWithAnnotation
*/
public function testTestWithVariousTypes()
{
$result = PHPUnit_Util_Test::getDataFromTestWithAnnotation('/**
* @testWith ("ab") (true) (null)
*/');
$this->assertEquals(array(array("ab"), array(true), array(null)), $result);
}

/**
* @covers PHPUnit_Util_Test::getDataFromTestWithAnnotation
*/
public function testTestWithAnnotationAfter()
{
$result = PHPUnit_Util_Test::getDataFromTestWithAnnotation("/**
* @testWith (1)
* (2)
* @annotation
*/");
$this->assertEquals(array(array(1), array(2)), $result);
}

/**
* @covers PHPUnit_Util_Test::getDataFromTestWithAnnotation
*/
public function testTestWithSimpleTextAfter()
{
$result = PHPUnit_Util_Test::getDataFromTestWithAnnotation("/**
* @testWith (1)
* (2)
* blah blah
*/");
$this->assertEquals(array(array(1), array(2)), $result);
}

/**
* @covers PHPUnit_Util_Test::getDataFromTestWithAnnotation
*/
public function testTestWithBraces()
{
$result = PHPUnit_Util_Test::getDataFromTestWithAnnotation('/**
* @testWith (")", "(")
* ("(", ")")
*/');
$this->assertEquals(array(array(")", "("), array("(", ")")), $result);
}

/**
* @covers PHPUnit_Util_Test::getDataFromTestWithAnnotation
*/
public function testTestWithCharacterEscape()
{
$result = PHPUnit_Util_Test::getDataFromTestWithAnnotation('/**
* @testWith ("\"", "\"")
*/');
$this->assertEquals(array(array('"', '"')), $result);
}

/**
* @covers PHPUnit_Util_Test::getDataFromTestWithAnnotation
*/
public function testTestWithMultiLineText()
{
$result = PHPUnit_Util_Test::getDataFromTestWithAnnotation("/**
* @testWith ('a
* bc')
*/");

$this->assertEquals(array(array("a\n bc")), $result);
}

/**
* @covers PHPUnit_Util_Test::getDataFromTestWithAnnotation
* @expectedException PHPUnit_Framework_Exception
*/
public function testTestWithThrowsProperExceptionIfDatasetCannotBeParsed()
{
PHPUnit_Util_Test::getDataFromTestWithAnnotation("/**
* @testWith (s)
*/");
}

/**
* @covers PHPUnit_Util_Test::getDependencies
* @todo Not sure what this test tests (name is misleading at least)
Expand Down

0 comments on commit bf1c416

Please sign in to comment.