diff --git a/bin/pest b/bin/pest
index 79d897c8..7419393f 100755
--- a/bin/pest
+++ b/bin/pest
@@ -4,6 +4,7 @@
use Pest\Kernel;
use Pest\Panic;
use Pest\TestCaseFilters\GitDirtyTestCaseFilter;
+use Pest\TestCaseMethodFilters\AssigneeTestCaseFilter;
use Pest\TestCaseMethodFilters\IssueTestCaseFilter;
use Pest\TestCaseMethodFilters\NotesTestCaseFilter;
use Pest\TestCaseMethodFilters\PrTestCaseFilter;
@@ -59,6 +60,16 @@ use Symfony\Component\Console\Output\ConsoleOutput;
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=')) {
unset($arguments[$key]);
} else if ($value === '--issue') {
@@ -142,6 +153,10 @@ use Symfony\Component\Console\Output\ConsoleOutput;
$testSuite->tests->addTestCaseMethodFilter(new NotesTestCaseFilter());
}
+ if ($assignee = $input->getParameterOption('--assignee')) {
+ $testSuite->tests->addTestCaseMethodFilter(new AssigneeTestCaseFilter((string) $assignee));
+ }
+
if ($issue = $input->getParameterOption('--issue')) {
$testSuite->tests->addTestCaseMethodFilter(new IssueTestCaseFilter((int) $issue));
}
diff --git a/src/Collision/Events.php b/src/Collision/Events.php
index 4810167d..0f83100f 100644
--- a/src/Collision/Events.php
+++ b/src/Collision/Events.php
@@ -41,22 +41,32 @@ final class Events
renderUsing(self::$output);
[
+ 'assignees' => $assignees,
'issues' => $issues,
'prs' => $prs,
] = $context;
- if ((($link = Context::getInstance()->issues) !== '' && ($link = Context::getInstance()->issues) !== '0')) {
+ if (($link = Context::getInstance()->issues) !== '') {
$issuesDescription = array_map(fn (int $issue): string => sprintf('#%s', 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('#%s', 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(
+ '@%s',
+ sprintf($link, $assignee),
+ $assignee,
+ ), $assignees);
+ }
+
+ if (count($assignees) > 0 || count($issues) > 0 || count($prs) > 0) {
$description .= ' '.implode(', ', array_merge(
$issuesDescription ?? [],
$prsDescription ?? [],
+ isset($assigneesDescription) ? ['['.implode(', ', $assigneesDescription).']'] : [],
));
}
diff --git a/src/Concerns/Testable.php b/src/Concerns/Testable.php
index 4db2887d..74c499b0 100644
--- a/src/Concerns/Testable.php
+++ b/src/Concerns/Testable.php
@@ -34,6 +34,11 @@ trait Testable
*/
private static string $__latestDescription;
+ /**
+ * The test's assignees.
+ */
+ private static array $__latestAssignees = [];
+
/**
* The test's notes.
*/
@@ -105,6 +110,7 @@ trait Testable
if ($test->hasMethod($name)) {
$method = $test->getMethod($name);
$this->__description = self::$__latestDescription = $method->description;
+ self::$__latestAssignees = $method->assignees;
self::$__latestNotes = $method->notes;
self::$__latestIssues = $method->issues;
self::$__latestPrs = $method->prs;
@@ -258,6 +264,7 @@ trait Testable
}
$this->__description = self::$__latestDescription = $description;
+ self::$__latestAssignees = $method->assignees;
self::$__latestNotes = $method->notes;
self::$__latestIssues = $method->issues;
self::$__latestPrs = $method->prs;
@@ -449,6 +456,7 @@ trait Testable
public static function getPrintableContext(): array
{
return [
+ 'assignees' => self::$__latestAssignees,
'issues' => self::$__latestIssues,
'prs' => self::$__latestPrs,
'notes' => self::$__latestNotes,
diff --git a/src/Configuration/Context.php b/src/Configuration/Context.php
index 97ae4189..d9098f8c 100644
--- a/src/Configuration/Context.php
+++ b/src/Configuration/Context.php
@@ -9,6 +9,13 @@ namespace Pest\Configuration;
*/
final class Context
{
+ /**
+ * The assignees link.
+ *
+ * @internal
+ */
+ public string $assignees = '';
+
/**
* The issues link.
*
@@ -44,6 +51,8 @@ final class Context
$this->issues = "https://github.com/{$project}/issues/%s";
$this->prs = "https://github.com/{$project}/pull/%s";
+ $this->assignees = 'https://github.com/%s';
+
return $this;
}
@@ -55,6 +64,8 @@ final class Context
$this->issues = "https://gitlab.com/{$project}/issues/%s";
$this->prs = "https://gitlab.com/{$project}/merge_requests/%s";
+ $this->assignees = 'https://gitlab.com/%s';
+
return $this;
}
@@ -66,6 +77,8 @@ final class Context
$this->issues = 'https://bitbucket.org/{$project}/issues/%s';
$this->prs = "https://bitbucket.org/{$project}/pull-requests/%s";
+ $this->assignees = 'https://bitbucket.org/%s';
+
return $this;
}
@@ -76,17 +89,21 @@ final class Context
{
$this->issues = "https://{$namespace}.atlassian.net/browse/{$project}-%s";
+ $this->assignees = "https://{$namespace}.atlassian.net/secure/ViewProfile?name=%s";
+
return $this;
}
/**
* 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->prs = $prs;
+ $this->assignees = $assignees;
+
return $this;
}
}
diff --git a/src/Factories/TestCaseMethodFactory.php b/src/Factories/TestCaseMethodFactory.php
index 7374a5a7..7c2e4248 100644
--- a/src/Factories/TestCaseMethodFactory.php
+++ b/src/Factories/TestCaseMethodFactory.php
@@ -56,6 +56,13 @@ final class TestCaseMethodFactory
*/
public array $issues = [];
+ /**
+ * The test assignees.
+ *
+ * @var array
+ */
+ public array $assignees = [];
+
/**
* The associated PRs numbers.
*
diff --git a/src/PendingCalls/TestCall.php b/src/PendingCalls/TestCall.php
index 7b2d7f85..50b041c6 100644
--- a/src/PendingCalls/TestCall.php
+++ b/src/PendingCalls/TestCall.php
@@ -390,6 +390,18 @@ final class TestCall
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).
*
@@ -401,7 +413,7 @@ final class TestCall
$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;
}
@@ -415,7 +427,7 @@ final class TestCall
{
$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;
}
diff --git a/src/TestCaseMethodFilters/AssigneeTestCaseFilter.php b/src/TestCaseMethodFilters/AssigneeTestCaseFilter.php
new file mode 100644
index 00000000..2a775693
--- /dev/null
+++ b/src/TestCaseMethodFilters/AssigneeTestCaseFilter.php
@@ -0,0 +1,27 @@
+assignees, fn ($assignee): bool => str_starts_with($assignee, $this->assignee)) !== [];
+ }
+}
diff --git a/tests/.snapshots/success.txt b/tests/.snapshots/success.txt
index a42466d5..f868a173 100644
--- a/tests/.snapshots/success.txt
+++ b/tests/.snapshots/success.txt
@@ -28,6 +28,11 @@
✓ it does not get executed before 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
✓ it gets executed before tests
✓ it do not get executed before each test
@@ -1537,4 +1542,4 @@
WARN Tests\Visual\Version
- visual snapshot of help command output
- Tests: 2 deprecated, 4 warnings, 5 incomplete, 2 notices, 13 todos, 24 skipped, 1076 passed (2628 assertions)
\ No newline at end of file
+ Tests: 2 deprecated, 4 warnings, 5 incomplete, 2 notices, 13 todos, 24 skipped, 1078 passed (2632 assertions)
\ No newline at end of file
diff --git a/tests/Features/Assignee.php b/tests/Features/Assignee.php
new file mode 100644
index 00000000..7995cb5a
--- /dev/null
+++ b/tests/Features/Assignee.php
@@ -0,0 +1,15 @@
+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']);
diff --git a/tests/Visual/Parallel.php b/tests/Visual/Parallel.php
index 53be829f..a6bbb0d3 100644
--- a/tests/Visual/Parallel.php
+++ b/tests/Visual/Parallel.php
@@ -16,7 +16,7 @@ $run = function () {
test('parallel', function () use ($run) {
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');
})->skipOnWindows();