Merge pull request #103 from nuernbergerA/feature/depends

Add support for PHPUnit's @depends
This commit is contained in:
Nuno Maduro
2020-06-21 17:10:58 +02:00
committed by GitHub
6 changed files with 96 additions and 12 deletions

View File

@ -129,16 +129,25 @@ trait TestCase
/**
* Runs the test.
*
* @return mixed
*
* @throws \Throwable
*/
public function __test(): void
public function __test()
{
$this->__callClosure($this->__test, func_get_args());
return $this->__callClosure($this->__test, func_get_args());
}
private function __callClosure(Closure $closure, array $arguments): void
/**
* @return mixed
*
* @throws \Throwable
*/
private function __callClosure(Closure $closure, array $arguments)
{
ExceptionTrace::ensure(function () use ($closure, $arguments) {
call_user_func_array(Closure::bind($closure, $this, get_class($this)), $arguments);
return ExceptionTrace::ensure(function () use ($closure, $arguments) {
return call_user_func_array(Closure::bind($closure, $this, get_class($this)), $arguments);
});
}

View File

@ -132,10 +132,14 @@ final class TestCaseFactory
$proxies = $this->proxies;
$factoryTest = $this->test;
$test = function () use ($chains, $proxies, $factoryTest): void {
/**
* @return mixed
*/
$test = function () use ($chains, $proxies, $factoryTest) {
$proxies->proxy($this);
$chains->chain($this);
call_user_func(Closure::bind($factoryTest, $this, get_class($this)), ...func_get_args());
return call_user_func(Closure::bind($factoryTest, $this, get_class($this)), ...func_get_args());
};
$className = $this->makeClassFromFilename($this->filename);

View File

@ -84,6 +84,18 @@ final class TestCall
return $this;
}
/**
* Sets the test depends.
*/
public function depends(string ...$tests): TestCall
{
$this->testCaseFactory
->factoryProxies
->add(Backtrace::file(), Backtrace::line(), 'setDependencies', [$tests]);
return $this;
}
/**
* Makes the test suite only this test case.
*/
@ -95,7 +107,7 @@ final class TestCall
}
/**
* Sets the test groups(s).
* Sets the test group(s).
*/
public function group(string ...$groups): TestCall
{

View File

@ -17,11 +17,15 @@ final class ExceptionTrace
/**
* Ensures the given closure reports
* the good execution context.
*
* @return mixed
*
* @throws \Throwable
*/
public static function ensure(Closure $closure): void
public static function ensure(Closure $closure)
{
try {
$closure();
return $closure();
} catch (Throwable $throwable) {
if (Str::startsWith($message = $throwable->getMessage(), self::UNDEFINED_METHOD)) {
$message = str_replace(self::UNDEFINED_METHOD, 'Call to undefined method ', $message);

View File

@ -49,6 +49,16 @@
✓ it creates unique test case names with ('Name 1', Pest\Plugin Object (), true) #3
✓ it creates unique test case names - count
WARN Tests\Features\Depends
✓ first
✓ second
✓ depends
✓ depends with ...params
✓ depends with defined arguments
✓ depends run test only once
s incomplete → incomplete
w depends on incomplete → This test depends on "P\Tests\Features\Depends::incomplete" which does not exist.
PASS Tests\Features\Exceptions
✓ it gives access the the underlying expectException
✓ it catch exceptions
@ -151,5 +161,6 @@
WARN Tests\Visual\Success
s visual snapshot of test suite on success
Tests: 6 skipped, 86 passed
Time: 3.58s
Tests: 1 warnings, 7 skipped, 85 passed
Time: 2.65s

View File

@ -0,0 +1,44 @@
<?php
$runCounter = 0;
test('first', function () use (&$runCounter) {
assertTrue(true);
$runCounter++;
return 'first';
});
test('second', function () use (&$runCounter) {
assertTrue(true);
$runCounter++;
return 'second';
});
test('depends', function () {
assertEquals(
['first', 'second'],
func_get_args()
);
})->depends('first', 'second');
test('depends with ...params', function (string ...$params) {
assertEquals(
['first', 'second'],
$params
);
})->depends('first', 'second');
test('depends with defined arguments', function (string $first, string $second) {
assertEquals('first', $first);
assertEquals('second', $second);
})->depends('first', 'second');
test('depends run test only once', function () use (&$runCounter) {
assertEquals(2, $runCounter);
})->depends('first', 'second');
test('incomplete')->skip('incomplete');
test('depends on incomplete')->depends('incomplete')->doesNotPerformAssertions();