mirror of
https://github.com/pestphp/pest.git
synced 2026-03-06 07:47:22 +01:00
Adds assignees
This commit is contained in:
15
bin/pest
15
bin/pest
@ -4,6 +4,7 @@
|
|||||||
use Pest\Kernel;
|
use Pest\Kernel;
|
||||||
use Pest\Panic;
|
use Pest\Panic;
|
||||||
use Pest\TestCaseFilters\GitDirtyTestCaseFilter;
|
use Pest\TestCaseFilters\GitDirtyTestCaseFilter;
|
||||||
|
use Pest\TestCaseMethodFilters\AssigneeTestCaseFilter;
|
||||||
use Pest\TestCaseMethodFilters\IssueTestCaseFilter;
|
use Pest\TestCaseMethodFilters\IssueTestCaseFilter;
|
||||||
use Pest\TestCaseMethodFilters\NotesTestCaseFilter;
|
use Pest\TestCaseMethodFilters\NotesTestCaseFilter;
|
||||||
use Pest\TestCaseMethodFilters\PrTestCaseFilter;
|
use Pest\TestCaseMethodFilters\PrTestCaseFilter;
|
||||||
@ -59,6 +60,16 @@ use Symfony\Component\Console\Output\ConsoleOutput;
|
|||||||
unset($arguments[$key]);
|
unset($arguments[$key]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (str_contains($value, '--assignee=')) {
|
||||||
|
unset($arguments[$key]);
|
||||||
|
} else if ($value === '--assignee') {
|
||||||
|
unset($arguments[$key]);
|
||||||
|
|
||||||
|
if (isset($arguments[$key + 1])) {
|
||||||
|
unset($arguments[$key + 1]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (str_contains($value, '--issue=')) {
|
if (str_contains($value, '--issue=')) {
|
||||||
unset($arguments[$key]);
|
unset($arguments[$key]);
|
||||||
} else if ($value === '--issue') {
|
} else if ($value === '--issue') {
|
||||||
@ -142,6 +153,10 @@ use Symfony\Component\Console\Output\ConsoleOutput;
|
|||||||
$testSuite->tests->addTestCaseMethodFilter(new NotesTestCaseFilter());
|
$testSuite->tests->addTestCaseMethodFilter(new NotesTestCaseFilter());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ($assignee = $input->getParameterOption('--assignee')) {
|
||||||
|
$testSuite->tests->addTestCaseMethodFilter(new AssigneeTestCaseFilter((string) $assignee));
|
||||||
|
}
|
||||||
|
|
||||||
if ($issue = $input->getParameterOption('--issue')) {
|
if ($issue = $input->getParameterOption('--issue')) {
|
||||||
$testSuite->tests->addTestCaseMethodFilter(new IssueTestCaseFilter((int) $issue));
|
$testSuite->tests->addTestCaseMethodFilter(new IssueTestCaseFilter((int) $issue));
|
||||||
}
|
}
|
||||||
|
|||||||
@ -41,22 +41,32 @@ final class Events
|
|||||||
renderUsing(self::$output);
|
renderUsing(self::$output);
|
||||||
|
|
||||||
[
|
[
|
||||||
|
'assignees' => $assignees,
|
||||||
'issues' => $issues,
|
'issues' => $issues,
|
||||||
'prs' => $prs,
|
'prs' => $prs,
|
||||||
] = $context;
|
] = $context;
|
||||||
|
|
||||||
if ((($link = Context::getInstance()->issues) !== '' && ($link = Context::getInstance()->issues) !== '0')) {
|
if (($link = Context::getInstance()->issues) !== '') {
|
||||||
$issuesDescription = array_map(fn (int $issue): string => sprintf('<a href="%s">#%s</a>', sprintf($link, $issue), $issue), $issues);
|
$issuesDescription = array_map(fn (int $issue): string => sprintf('<a href="%s">#%s</a>', sprintf($link, $issue), $issue), $issues);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((($link = Context::getInstance()->prs) !== '' && ($link = Context::getInstance()->prs) !== '0')) {
|
if (($link = Context::getInstance()->prs) !== '') {
|
||||||
$prsDescription = array_map(fn (int $pr): string => sprintf('<a href="%s">#%s</a>', sprintf($link, $pr), $pr), $prs);
|
$prsDescription = array_map(fn (int $pr): string => sprintf('<a href="%s">#%s</a>', sprintf($link, $pr), $pr), $prs);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (count($issues) > 0 || count($prs) > 0) {
|
if (($link = Context::getInstance()->assignees) !== '' && count($assignees) > 0) {
|
||||||
|
$assigneesDescription = array_map(fn (string $assignee): string => sprintf(
|
||||||
|
'<a href="%s">@%s</a>',
|
||||||
|
sprintf($link, $assignee),
|
||||||
|
$assignee,
|
||||||
|
), $assignees);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (count($assignees) > 0 || count($issues) > 0 || count($prs) > 0) {
|
||||||
$description .= ' '.implode(', ', array_merge(
|
$description .= ' '.implode(', ', array_merge(
|
||||||
$issuesDescription ?? [],
|
$issuesDescription ?? [],
|
||||||
$prsDescription ?? [],
|
$prsDescription ?? [],
|
||||||
|
isset($assigneesDescription) ? ['['.implode(', ', $assigneesDescription).']'] : [],
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -34,6 +34,11 @@ trait Testable
|
|||||||
*/
|
*/
|
||||||
private static string $__latestDescription;
|
private static string $__latestDescription;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The test's assignees.
|
||||||
|
*/
|
||||||
|
private static array $__latestAssignees = [];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The test's notes.
|
* The test's notes.
|
||||||
*/
|
*/
|
||||||
@ -105,6 +110,7 @@ trait Testable
|
|||||||
if ($test->hasMethod($name)) {
|
if ($test->hasMethod($name)) {
|
||||||
$method = $test->getMethod($name);
|
$method = $test->getMethod($name);
|
||||||
$this->__description = self::$__latestDescription = $method->description;
|
$this->__description = self::$__latestDescription = $method->description;
|
||||||
|
self::$__latestAssignees = $method->assignees;
|
||||||
self::$__latestNotes = $method->notes;
|
self::$__latestNotes = $method->notes;
|
||||||
self::$__latestIssues = $method->issues;
|
self::$__latestIssues = $method->issues;
|
||||||
self::$__latestPrs = $method->prs;
|
self::$__latestPrs = $method->prs;
|
||||||
@ -258,6 +264,7 @@ trait Testable
|
|||||||
}
|
}
|
||||||
|
|
||||||
$this->__description = self::$__latestDescription = $description;
|
$this->__description = self::$__latestDescription = $description;
|
||||||
|
self::$__latestAssignees = $method->assignees;
|
||||||
self::$__latestNotes = $method->notes;
|
self::$__latestNotes = $method->notes;
|
||||||
self::$__latestIssues = $method->issues;
|
self::$__latestIssues = $method->issues;
|
||||||
self::$__latestPrs = $method->prs;
|
self::$__latestPrs = $method->prs;
|
||||||
@ -449,6 +456,7 @@ trait Testable
|
|||||||
public static function getPrintableContext(): array
|
public static function getPrintableContext(): array
|
||||||
{
|
{
|
||||||
return [
|
return [
|
||||||
|
'assignees' => self::$__latestAssignees,
|
||||||
'issues' => self::$__latestIssues,
|
'issues' => self::$__latestIssues,
|
||||||
'prs' => self::$__latestPrs,
|
'prs' => self::$__latestPrs,
|
||||||
'notes' => self::$__latestNotes,
|
'notes' => self::$__latestNotes,
|
||||||
|
|||||||
@ -9,6 +9,13 @@ namespace Pest\Configuration;
|
|||||||
*/
|
*/
|
||||||
final class Context
|
final class Context
|
||||||
{
|
{
|
||||||
|
/**
|
||||||
|
* The assignees link.
|
||||||
|
*
|
||||||
|
* @internal
|
||||||
|
*/
|
||||||
|
public string $assignees = '';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The issues link.
|
* The issues link.
|
||||||
*
|
*
|
||||||
@ -44,6 +51,8 @@ final class Context
|
|||||||
$this->issues = "https://github.com/{$project}/issues/%s";
|
$this->issues = "https://github.com/{$project}/issues/%s";
|
||||||
$this->prs = "https://github.com/{$project}/pull/%s";
|
$this->prs = "https://github.com/{$project}/pull/%s";
|
||||||
|
|
||||||
|
$this->assignees = 'https://github.com/%s';
|
||||||
|
|
||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -55,6 +64,8 @@ final class Context
|
|||||||
$this->issues = "https://gitlab.com/{$project}/issues/%s";
|
$this->issues = "https://gitlab.com/{$project}/issues/%s";
|
||||||
$this->prs = "https://gitlab.com/{$project}/merge_requests/%s";
|
$this->prs = "https://gitlab.com/{$project}/merge_requests/%s";
|
||||||
|
|
||||||
|
$this->assignees = 'https://gitlab.com/%s';
|
||||||
|
|
||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -66,6 +77,8 @@ final class Context
|
|||||||
$this->issues = 'https://bitbucket.org/{$project}/issues/%s';
|
$this->issues = 'https://bitbucket.org/{$project}/issues/%s';
|
||||||
$this->prs = "https://bitbucket.org/{$project}/pull-requests/%s";
|
$this->prs = "https://bitbucket.org/{$project}/pull-requests/%s";
|
||||||
|
|
||||||
|
$this->assignees = 'https://bitbucket.org/%s';
|
||||||
|
|
||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -76,17 +89,21 @@ final class Context
|
|||||||
{
|
{
|
||||||
$this->issues = "https://{$namespace}.atlassian.net/browse/{$project}-%s";
|
$this->issues = "https://{$namespace}.atlassian.net/browse/{$project}-%s";
|
||||||
|
|
||||||
|
$this->assignees = "https://{$namespace}.atlassian.net/secure/ViewProfile?name=%s";
|
||||||
|
|
||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the test context to custom.
|
* Sets the test context to custom.
|
||||||
*/
|
*/
|
||||||
public function using(string $issues, string $prs): self
|
public function using(string $issues, string $prs, string $assignees): self
|
||||||
{
|
{
|
||||||
$this->issues = $issues;
|
$this->issues = $issues;
|
||||||
$this->prs = $prs;
|
$this->prs = $prs;
|
||||||
|
|
||||||
|
$this->assignees = $assignees;
|
||||||
|
|
||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -56,6 +56,13 @@ final class TestCaseMethodFactory
|
|||||||
*/
|
*/
|
||||||
public array $issues = [];
|
public array $issues = [];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The test assignees.
|
||||||
|
*
|
||||||
|
* @var array<int, string>
|
||||||
|
*/
|
||||||
|
public array $assignees = [];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The associated PRs numbers.
|
* The associated PRs numbers.
|
||||||
*
|
*
|
||||||
|
|||||||
@ -390,6 +390,18 @@ final class TestCall
|
|||||||
return $this->issue($number);
|
return $this->issue($number);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the test assignee(s).
|
||||||
|
*/
|
||||||
|
public function assignee(array|string $assignee): self
|
||||||
|
{
|
||||||
|
$assignees = is_array($assignee) ? $assignee : [$assignee];
|
||||||
|
|
||||||
|
$this->testCaseMethod->assignees = array_unique(array_merge($this->testCaseMethod->assignees, $assignees));
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Associates the test with the given pull request(s).
|
* Associates the test with the given pull request(s).
|
||||||
*
|
*
|
||||||
@ -401,7 +413,7 @@ final class TestCall
|
|||||||
|
|
||||||
$number = array_map(fn (string|int $number): int => (int) ltrim((string) $number, '#'), $number);
|
$number = array_map(fn (string|int $number): int => (int) ltrim((string) $number, '#'), $number);
|
||||||
|
|
||||||
$this->testCaseMethod->prs = array_merge($this->testCaseMethod->issues, $number);
|
$this->testCaseMethod->prs = array_unique(array_merge($this->testCaseMethod->issues, $number));
|
||||||
|
|
||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
@ -415,7 +427,7 @@ final class TestCall
|
|||||||
{
|
{
|
||||||
$notes = is_array($note) ? $note : [$note];
|
$notes = is_array($note) ? $note : [$note];
|
||||||
|
|
||||||
$this->testCaseMethod->notes = array_merge($this->testCaseMethod->notes, $notes);
|
$this->testCaseMethod->notes = array_unique(array_merge($this->testCaseMethod->notes, $notes));
|
||||||
|
|
||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
|||||||
27
src/TestCaseMethodFilters/AssigneeTestCaseFilter.php
Normal file
27
src/TestCaseMethodFilters/AssigneeTestCaseFilter.php
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace Pest\TestCaseMethodFilters;
|
||||||
|
|
||||||
|
use Pest\Contracts\TestCaseMethodFilter;
|
||||||
|
use Pest\Factories\TestCaseMethodFactory;
|
||||||
|
|
||||||
|
final readonly class AssigneeTestCaseFilter implements TestCaseMethodFilter
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Create a new filter instance.
|
||||||
|
*/
|
||||||
|
public function __construct(private string $assignee)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Filter the test case methods.
|
||||||
|
*/
|
||||||
|
public function accept(TestCaseMethodFactory $factory): bool
|
||||||
|
{
|
||||||
|
return array_filter($factory->assignees, fn ($assignee): bool => str_starts_with($assignee, $this->assignee)) !== [];
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -28,6 +28,11 @@
|
|||||||
✓ it does not get executed before the test
|
✓ it does not get executed before the test
|
||||||
✓ it gets executed after the test
|
✓ it gets executed after the test
|
||||||
|
|
||||||
|
PASS Tests\Features\Assignee
|
||||||
|
✓ it may be associated with an assignee [@nunomaduro, @taylorotwell]
|
||||||
|
✓ nested → it may be associated with an assignee [@nunomaduro, @jamesbrooks, @joedixon, @taylorotwell]
|
||||||
|
// an note between an the assignee
|
||||||
|
|
||||||
PASS Tests\Features\BeforeAll
|
PASS Tests\Features\BeforeAll
|
||||||
✓ it gets executed before tests
|
✓ it gets executed before tests
|
||||||
✓ it do not get executed before each test
|
✓ it do not get executed before each test
|
||||||
@ -1537,4 +1542,4 @@
|
|||||||
WARN Tests\Visual\Version
|
WARN Tests\Visual\Version
|
||||||
- visual snapshot of help command output
|
- visual snapshot of help command output
|
||||||
|
|
||||||
Tests: 2 deprecated, 4 warnings, 5 incomplete, 2 notices, 13 todos, 24 skipped, 1076 passed (2628 assertions)
|
Tests: 2 deprecated, 4 warnings, 5 incomplete, 2 notices, 13 todos, 24 skipped, 1078 passed (2632 assertions)
|
||||||
15
tests/Features/Assignee.php
Normal file
15
tests/Features/Assignee.php
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
beforeEach(function () {
|
||||||
|
expect(true)->toBeTrue();
|
||||||
|
})->assignee('nunomaduro');
|
||||||
|
|
||||||
|
it('may be associated with an assignee', function () {
|
||||||
|
expect(true)->toBeTrue();
|
||||||
|
})->assignee('taylorotwell');
|
||||||
|
|
||||||
|
describe('nested', function () {
|
||||||
|
it('may be associated with an assignee', function () {
|
||||||
|
expect(true)->toBeTrue();
|
||||||
|
})->assignee('taylorotwell');
|
||||||
|
})->assignee('nunomaduro')->note('an note between an the assignee')->assignee(['jamesbrooks', 'joedixon']);
|
||||||
@ -16,7 +16,7 @@ $run = function () {
|
|||||||
|
|
||||||
test('parallel', function () use ($run) {
|
test('parallel', function () use ($run) {
|
||||||
expect($run('--exclude-group=integration'))
|
expect($run('--exclude-group=integration'))
|
||||||
->toContain('Tests: 2 deprecated, 4 warnings, 5 incomplete, 2 notices, 13 todos, 19 skipped, 1062 passed (2596 assertions)')
|
->toContain('Tests: 2 deprecated, 4 warnings, 5 incomplete, 2 notices, 13 todos, 19 skipped, 1064 passed (2600 assertions)')
|
||||||
->toContain('Parallel: 3 processes');
|
->toContain('Parallel: 3 processes');
|
||||||
})->skipOnWindows();
|
})->skipOnWindows();
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user