feat: note()

This commit is contained in:
Nuno Maduro
2024-06-27 01:26:54 +01:00
parent d9252e85d6
commit 5c3bf469d5
10 changed files with 118 additions and 3 deletions

View File

@ -4,6 +4,7 @@
use Pest\Kernel;
use Pest\Panic;
use Pest\TestCaseFilters\GitDirtyTestCaseFilter;
use Pest\TestCaseMethodFilters\NotesTestCaseFilter;
use Pest\TestCaseMethodFilters\TodoTestCaseFilter;
use Pest\TestSuite;
use Symfony\Component\Console\Input\ArgvInput;
@ -17,6 +18,7 @@ use Symfony\Component\Console\Output\ConsoleOutput;
$dirty = false;
$todo = false;
$notes = false;
foreach ($arguments as $key => $value) {
if ($value === '--compact') {
@ -43,6 +45,11 @@ use Symfony\Component\Console\Output\ConsoleOutput;
unset($arguments[$key]);
}
if ($value === '--notes') {
$notes = true;
unset($arguments[$key]);
}
if (str_contains($value, '--teamcity')) {
unset($arguments[$key]);
$arguments[] = '--no-output';
@ -81,6 +88,10 @@ use Symfony\Component\Console\Output\ConsoleOutput;
$testSuite->tests->addTestCaseMethodFilter(new TodoTestCaseFilter());
}
if ($notes) {
$testSuite->tests->addTestCaseMethodFilter(new NotesTestCaseFilter());
}
$isDecorated = $input->getParameterOption('--colors', 'always') !== 'never';
$output = new ConsoleOutput(ConsoleOutput::VERBOSITY_NORMAL, $isDecorated);

View File

@ -29,6 +29,11 @@ trait Testable
*/
private string $__description;
/**
* The test's notes.
*/
private static array $__latestNotes = [];
/**
* The test's latest description.
*/
@ -74,6 +79,18 @@ trait Testable
*/
private array $__snapshotChanges = [];
/**
* Adds a new "note" to the Test Case.
*/
public function note(array|string $note): self
{
$note = is_array($note) ? $note : [$note];
self::$__latestNotes = array_merge(self::$__latestNotes, $note);
return $this;
}
/**
* Resets the test case static properties.
*/
@ -95,6 +112,7 @@ trait Testable
if ($test->hasMethod($name)) {
$method = $test->getMethod($name);
$this->__description = self::$__latestDescription = $method->description;
self::$__latestNotes = $method->notes;
$this->__describing = $method->describing;
$this->__test = $method->getClosure($this);
}
@ -224,6 +242,7 @@ trait Testable
}
$this->__description = self::$__latestDescription = $description;
self::$__latestNotes = $method->notes;
parent::setUp();
@ -405,4 +424,12 @@ trait Testable
{
return self::$__latestDescription;
}
/**
* The latest printable test case notes.
*/
public static function getPrintableTestCaseMethodNotes(): array
{
return self::$__latestNotes;
}
}

View File

@ -49,6 +49,13 @@ final class TestCaseMethodFactory
*/
public bool $todo = false;
/**
* The test's notes.
*
* @var array<int, string>
*/
public array $notes = [];
/**
* The test's datasets.
*

View File

@ -364,6 +364,20 @@ final class TestCall
return $this;
}
/**
* Adds a note to the test.
*
* @param array<int, string>|string $note
*/
public function note(array|string $note): self
{
$notes = is_array($note) ? $note : [$note];
$this->testCaseMethod->notes = array_merge($this->testCaseMethod->notes, $notes);
return $this;
}
/**
* Sets the covered classes or methods.
*/

View File

@ -123,6 +123,9 @@ final class Help implements HandlesArguments
], [
'arg' => '--todos',
'desc' => 'Output to standard output the list of todos',
], [
'arg' => '--notes',
'desc' => 'Output to standard output tests with notes',
], [
'arg' => '--retry',
'desc' => 'Run non-passing tests first and stop execution upon first error or failure',

View File

@ -34,7 +34,7 @@ final class Parallel implements HandlesArguments
/**
* @var string[]
*/
private const UNSUPPORTED_ARGUMENTS = ['--todo', '--todos', '--retry'];
private const UNSUPPORTED_ARGUMENTS = ['--todo', '--todos', '--retry', '--notes'];
/**
* Whether the given command line arguments indicate that the test suite should be run in parallel.
@ -42,6 +42,7 @@ final class Parallel implements HandlesArguments
public static function isEnabled(): bool
{
$argv = new ArgvInput();
if ($argv->hasParameterOption('--parallel')) {
return true;
}

View File

@ -118,7 +118,7 @@ final class TestRepository
*/
public function get(string $filename): ?TestCaseFactory
{
return $this->testCases[$filename];
return $this->testCases[$filename] ?? null;
}
/**

View File

@ -31,7 +31,7 @@ final class ExceptionTrace
$message = str_replace(self::UNDEFINED_METHOD, 'Call to undefined method ', $message);
if (class_exists((string) $class) && (is_countable(class_parents($class)) ? count(class_parents($class)) : 0) > 0 && array_values(class_parents($class))[0] === TestCase::class) { // @phpstan-ignore-line
$message .= '. Did you forget to use the [uses()] function? Read more at: https://pestphp.com/docs/configuring-tests';
$message .= '. Did you forget to use the [pest()->uses()] function? Read more at: https://pestphp.com/docs/configuring-tests';
}
Reflection::setPropertyValue($throwable, 'message', $message);

View File

@ -0,0 +1,16 @@
<?php
declare(strict_types=1);
namespace Pest\TestCaseMethodFilters;
use Pest\Contracts\TestCaseMethodFilter;
use Pest\Factories\TestCaseMethodFactory;
final class NotesTestCaseFilter implements TestCaseMethodFilter
{
public function accept(TestCaseMethodFactory $factory): bool
{
return count($factory->notes) > 0;
}
}

36
tests/Features/Note.php Normal file
View File

@ -0,0 +1,36 @@
<?php
beforeEach(function () {
$this->note('This is before each runtime note');
})->note('This is before each static note');
it('may have a static note', function () {
expect(true)->toBeTrue();
})->note('This is a note');
it('may have a runtime note', function () {
expect(true)->toBeTrue(true);
$this->note('This is a runtime note');
});
it('may have static note and runtime note', function () {
expect(true)->toBeTrue(true);
$this->note('This is a runtime note');
})->note('This is a static note');
describe('nested', function () {
it('may have static note and runtime note', function () {
expect(true)->toBeTrue(true);
$this->note('This is a runtime note within describe');
})->note('This is a static note within describe');
})->note('This is describe static note');
test('multiple notes', function () {
$this->note([
'This is a runtime note',
'This is another runtime note',
]);
});