Skip to content

Commit

Permalink
TestCase: support for @throws annotation [Closes nette#16]
Browse files Browse the repository at this point in the history
  • Loading branch information
milo authored and dg committed Jul 19, 2013
1 parent 6c19726 commit e33c8e5
Show file tree
Hide file tree
Showing 3 changed files with 157 additions and 3 deletions.
25 changes: 22 additions & 3 deletions Tester/Framework/TestCase.php
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,16 @@ public function run($method = NULL)
}

$data = array();
$info = Helpers::parseDocComment($method->getDocComment()) + array('dataprovider' => NULL);
$info = Helpers::parseDocComment($method->getDocComment()) + array('dataprovider' => NULL, 'throws' => NULL);

if ($info['throws'] === TRUE) {
throw new TestCaseException("Missing class name in @throws annotation for {$method->getName()}().");
} elseif (is_array($info['throws'])) {
throw new TestCaseException("Annotation @throws for {$method->getName()}() can be specified only once.");
} else {
$throws = preg_split('#\s+#', $info['throws'], 2) + array(NULL, NULL);
}

foreach ((array) $info['dataprovider'] as $provider) {
$res = $this->getData($provider);
if (!is_array($res)) {
Expand All @@ -51,7 +60,17 @@ public function run($method = NULL)

foreach ($data as $key => $args) {
try {
$this->runTest($method->getName(), $args);
if ($info['throws']) {
$tmp = $this;
$e = Assert::error(function() use ($tmp, $method, $args) {
$tmp->runTest($method->getName(), $args);
}, $throws[0], $throws[1]);
if ($e instanceof AssertException) {
throw $e;
}
} else {
$this->runTest($method->getName(), $args);
}
} catch (AssertException $e) {
$e->message .= " in {$method->getName()}" . (substr(Dumper::toLine($args), 5));
throw $e;
Expand Down Expand Up @@ -90,7 +109,7 @@ protected function getData($provider)
return DataProvider::load(dirname($rc->getFileName()) . '/' . $file, $query);
} else {
return $this->$provider();
}
}
}


Expand Down
100 changes: 100 additions & 0 deletions tests/TestCase.annotationThrows.phpt
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
<?php

use Tester\Assert;

require __DIR__ . '/bootstrap.php';


class MyException extends Exception
{
}

class MyTest extends Tester\TestCase
{
/** @throws Exception */
public function testThrows()
{
throw new Exception;
}

/** @throws Exception */
public function testThrowsButDont()
{
}

/** @throws Exception With message */
public function testThrowsMessage()
{
throw new Exception('With message');
}

/** @throws Exception */
public function testFailAssertPass()
{
Assert::fail('failed');
}

/** @throws MyException */
public function testThrowsBadClass()
{
throw new Exception;
}

/** @throws Exception With message */
public function testThrowsBadMessage()
{
throw new Exception('Bad message');
}

// Without @throws
public function testWithoutThrows()
{
throw new Exception;
}

public function dataProvider()
{
return array(array(1));
}

/**
* @dataprovider dataProvider
* @throws Exception
*/
public function testThrowsWithDataprovider($x)
{
}
}


$test = new MyTest;
$test->run('testThrows');
$test->run('testThrowsMessage');

Assert::exception(function() use ($test) {
$test->run('testThrowsButDont');
}, 'Tester\AssertException', 'Exception was expected, but none was thrown in testThrowsButDont()');

Assert::exception(function() use ($test) {
$test->run('testFailAssertPass');
}, 'Tester\AssertException', 'failed in testFailAssertPass()');

Assert::exception(function() use ($test) {
$test->run('testThrowsBadClass');
}, 'Tester\AssertException', 'MyException was expected but got Exception in testThrowsBadClass()');

Assert::exception(function() use ($test) {
$test->run('testThrowsBadMessage');
}, 'Tester\AssertException', "Exception with a message matching 'With message' was expected but got 'Bad message' in testThrowsBadMessage()");

Assert::exception(function() use ($test) {
$test->run('testWithoutThrows');
}, 'Exception');

Assert::exception(function() use ($test) {
$test->run('testThrowsWithDataprovider');
}, 'Exception', 'Exception was expected, but none was thrown in testThrowsWithDataprovider(1)');

Assert::exception(function() use ($test) {
$test->run('testUndefinedMethod');
}, 'ReflectionException', 'Method testUndefinedMethod does not exist');
35 changes: 35 additions & 0 deletions tests/TestCase.annotationThrows.syntax.phpt
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
<?php

use Tester\Assert;

require __DIR__ . '/bootstrap.php';


class MyTest extends Tester\TestCase
{
/**
* @throws
*/
public function testThrowsNoClass()
{
}

/**
* @throws Exception
* @throws Exception
*/
public function testThrowsMultiple()
{
}

}

$test = new MyTest;

Assert::exception(function() use ($test) {
$test->run('testThrowsNoClass');
}, 'Tester\TestCaseException', 'Missing class name in @throws annotation for testThrowsNoClass().');

Assert::exception(function() use ($test) {
$test->run('testThrowsMultiple');
}, 'Tester\TestCaseException', 'Annotation @throws for testThrowsMultiple() can be specified only once.');

0 comments on commit e33c8e5

Please sign in to comment.