Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
feat: allows to use test calls on before each calls
  • Loading branch information
nunomaduro committed May 1, 2023
1 parent cddddc3 commit 97898a0
Show file tree
Hide file tree
Showing 14 changed files with 118 additions and 26 deletions.
2 changes: 1 addition & 1 deletion composer.json
Expand Up @@ -50,7 +50,7 @@
},
"require-dev": {
"pestphp/pest-dev-tools": "^2.7.0",
"symfony/process": "^6.2.8"
"symfony/process": "^6.2.10"
},
"minimum-stability": "stable",
"config": {
Expand Down
2 changes: 1 addition & 1 deletion src/Concerns/Testable.php
Expand Up @@ -181,7 +181,7 @@ protected function setUp(): void

parent::setUp();

$beforeEach = TestSuite::getInstance()->beforeEach->get(self::$__filename);
$beforeEach = TestSuite::getInstance()->beforeEach->get(self::$__filename)[1];

if ($this->__beforeEach instanceof Closure) {
$beforeEach = ChainableClosure::from($this->__beforeEach, $beforeEach);
Expand Down
2 changes: 1 addition & 1 deletion src/Functions.php
Expand Up @@ -43,7 +43,7 @@ function beforeAll(Closure $closure): void
/**
* Runs the given closure before each test in the current file.
*
* @return HigherOrderTapProxy<TestCall|TestCase>|TestCall|mixed
* @return HigherOrderTapProxy<TestCall|TestCase>|TestCall|TestCase|mixed
*/
function beforeEach(Closure $closure = null): BeforeEachCall
{
Expand Down
33 changes: 24 additions & 9 deletions src/PendingCalls/BeforeEachCall.php
Expand Up @@ -19,12 +19,17 @@ final class BeforeEachCall
/**
* Holds the before each closure.
*/
private readonly \Closure $closure;
private readonly Closure $closure;

/**
* The calls that should be proxied.
* The test call proxies.
*/
private readonly HigherOrderMessageCollection $proxies;
private readonly HigherOrderMessageCollection $testCallProxies;

/**
* The test case proxies.
*/
private readonly HigherOrderMessageCollection $testCaseProxies;

/**
* Creates a new Pending Call.
Expand All @@ -36,21 +41,25 @@ public function __construct(
) {
$this->closure = $closure instanceof Closure ? $closure : NullClosure::create();

$this->proxies = new HigherOrderMessageCollection();
$this->testCallProxies = new HigherOrderMessageCollection();
$this->testCaseProxies = new HigherOrderMessageCollection();
}

/**
* Creates the Call.
*/
public function __destruct()
{
$proxies = $this->proxies;
$testCaseProxies = $this->testCaseProxies;

$this->testSuite->beforeEach->set(
$this->filename,
ChainableClosure::from(function () use ($proxies): void {
$proxies->chain($this);
}, $this->closure)
function (TestCall $testCall): void {
$this->testCallProxies->chain($testCall);
},
ChainableClosure::from(function () use ($testCaseProxies): void {
$testCaseProxies->chain($this);
}, $this->closure),
);
}

Expand All @@ -61,7 +70,13 @@ public function __destruct()
*/
public function __call(string $name, array $arguments): self
{
$this->proxies
if (method_exists(TestCall::class, $name)) {
$this->testCallProxies->add(Backtrace::file(), Backtrace::line(), $name, $arguments);

return $this;
}

$this->testCaseProxies
->add(Backtrace::file(), Backtrace::line(), $name, $arguments);

return $this;
Expand Down
7 changes: 5 additions & 2 deletions src/PendingCalls/TestCall.php
Expand Up @@ -40,12 +40,15 @@ final class TestCall
*/
public function __construct(
private readonly TestSuite $testSuite,
string $filename,
private readonly string $filename,
string $description = null,
Closure $closure = null
) {
$this->testCaseMethod = new TestCaseMethodFactory($filename, $description, $closure);

$this->descriptionLess = $description === null;

$this->testSuite->beforeEach->get($filename)[0]($this);
}

/**
Expand Down Expand Up @@ -167,7 +170,7 @@ public function skip(Closure|bool|string $conditionOrMessage = true, string $mes

$this->testCaseMethod
->chains
->addWhen($condition, Backtrace::file(), Backtrace::line(), 'markTestSkipped', [$message]);
->addWhen($condition, $this->filename, Backtrace::line(), 'markTestSkipped', [$message]);

return $this;
}
Expand Down
17 changes: 12 additions & 5 deletions src/Repositories/BeforeEachRepository.php
Expand Up @@ -14,27 +14,34 @@
final class BeforeEachRepository
{
/**
* @var array<string, Closure>
* @var array<string, array{0: Closure, 1: Closure}>
*/
private array $state = [];

/**
* Sets a before each closure.
*/
public function set(string $filename, Closure $closure): void
public function set(string $filename, Closure $beforeEachTestCall, Closure $beforeEachTestCase): void
{
if (array_key_exists($filename, $this->state)) {
throw new BeforeEachAlreadyExist($filename);
}

$this->state[$filename] = $closure;
$this->state[$filename] = [$beforeEachTestCall, $beforeEachTestCase];
}

/**
* Gets a before each closure by the given filename.
*
* @return array{0: Closure, 1: Closure}
*/
public function get(string $filename): Closure
public function get(string $filename): array
{
return $this->state[$filename] ?? NullClosure::create();
$closures = $this->state[$filename] ?? [];

return [
$closures[0] ?? NullClosure::create(),
$closures[1] ?? NullClosure::create(),
];
}
}
4 changes: 1 addition & 3 deletions src/Support/Backtrace.php
Expand Up @@ -104,8 +104,6 @@ public static function line(): int
{
$trace = debug_backtrace(self::BACKTRACE_OPTIONS)[1];

assert(array_key_exists('line', $trace));

return $trace['line'];
return $trace['line'] ?? 0;
}
}
18 changes: 17 additions & 1 deletion tests/.snapshots/success.txt
Expand Up @@ -22,6 +22,22 @@
✓ it gets executed before each test
✓ it gets executed before each test once again

PASS Tests\Features\BeforeEachProxiesToTestCallWithExpectations
✓ runs 1
✓ runs 2
✓ runs 3

WARN Tests\Features\BeforeEachProxiesToTestCallWithSkip
- does not run 1
- does not run 2
- does not run 3

TODO Tests\Features\BeforeEachProxiesToTestCallWithTodo - 4 todos
↓ is marked as todo 1
↓ is marked as todo 2
↓ is marked as todo 3
↓ shouldBeMarkedAsTodo

WARN Tests\Features\Coverage
✓ it has plugin
- it adds coverage if --coverage exist → Coverage is not available
Expand Down Expand Up @@ -1017,4 +1033,4 @@
PASS Tests\Visual\Version
✓ visual snapshot of help command output

Tests: 1 deprecated, 3 warnings, 4 incomplete, 1 notice, 4 todos, 14 skipped, 711 passed (1719 assertions)
Tests: 1 deprecated, 3 warnings, 4 incomplete, 1 notice, 8 todos, 17 skipped, 714 passed (1722 assertions)
8 changes: 7 additions & 1 deletion tests/.snapshots/todo.txt
@@ -1,3 +1,9 @@
TODO Tests\Features\BeforeEachProxiesToTestCallWithTodo - 4 todos
↓ is marked as todo 1
↓ is marked as todo 2
↓ is marked as todo 3
↓ shouldBeMarkedAsTodo

TODO Tests\Features\DatasetsTests - 1 todo
↓ forbids to define tests in Datasets dirs and Datasets.php files

Expand All @@ -9,4 +15,4 @@
PASS Tests\CustomTestCase\ExecutedTest
✓ that gets executed

Tests: 4 todos, 1 passed (1 assertions)
Tests: 8 todos, 1 passed (1 assertions)
15 changes: 15 additions & 0 deletions tests/Features/BeforeEachProxiesToTestCallWithExpectations.php
@@ -0,0 +1,15 @@
<?php

beforeEach()->expect(true)->toBeTrue();

test('runs 1', function () {
// This test did performs assertions...
});

test('runs 2', function () {
// This test did performs assertions...
});

test('runs 3', function () {
// This test did performs assertions...
});
15 changes: 15 additions & 0 deletions tests/Features/BeforeEachProxiesToTestCallWithSkip.php
@@ -0,0 +1,15 @@
<?php

beforeEach()->skip();

test('does not run 1', function () {
$this->fail('This test should not run');
});

test('does not run 2', function () {
$this->fail('This test should not run');
});

test('does not run 3', function () {
$this->fail('This test should not run');
});
15 changes: 15 additions & 0 deletions tests/Features/BeforeEachProxiesToTestCallWithTodo.php
@@ -0,0 +1,15 @@
<?php

beforeEach()->todo();

test('is marked as todo 1', function () {
$this->fail('This test should not run');
});

test('is marked as todo 2', function () {
$this->fail('This test should not run');
});

test('is marked as todo 3');

test()->shouldBeMarkedAsTodo();
2 changes: 1 addition & 1 deletion tests/Visual/Parallel.php
Expand Up @@ -18,7 +18,7 @@

test('parallel', function () use ($run) {
expect($run('--exclude-group=integration'))
->toContain('Tests: 1 deprecated, 3 warnings, 4 incomplete, 1 notice, 4 todos, 11 skipped, 699 passed (1704 assertions)')
->toContain('Tests: 1 deprecated, 3 warnings, 4 incomplete, 1 notice, 8 todos, 14 skipped, 702 passed (1707 assertions)')
->toContain('Parallel: 3 processes');
})->skipOnWindows();

Expand Down
4 changes: 3 additions & 1 deletion tests/Visual/Todo.php
Expand Up @@ -11,7 +11,9 @@

expect($process->getExitCode())->toBe(0);

return preg_replace('#\\x1b[[][^A-Za-z]*[A-Za-z]#', '', $process->getOutput());
$outputContent = preg_replace('#\\x1b[[][^A-Za-z]*[A-Za-z]#', '', $process->getOutput());

return $outputContent;
};

$snapshot = function ($name) {
Expand Down

0 comments on commit 97898a0

Please sign in to comment.