Compare commits

...

5 Commits

Author SHA1 Message Date
3a4329ddc7 release: 4.3.2 2026-01-28 01:01:19 +00:00
dd01229d7b Merge pull request #1606 from smirok/teamcity-fix-for-describe-tests-with-dataset
fix: replace `substr` with `mb_substr` in Str::beforeLast to ensure multibyte string compatibility and correct TeamCity test names for datasets in "describe" blocks
2026-01-15 01:52:01 +00:00
c7e4efcea4 fix: replace substr with mb_substr in Str::beforeLast to ensure multibyte string compatibility and correct TeamCity test names for datasets in "describe" blocks 2026-01-14 00:55:35 +01:00
df3205e814 Merge pull request #1554 from pindab0ter/feature/extend-closure-this
Specify closure this for extend
2026-01-13 01:19:47 +00:00
b7b16096db Specify closure this for extend 2025-10-29 11:20:08 +01:00
11 changed files with 30 additions and 13 deletions

View File

@ -18,19 +18,19 @@
], ],
"require": { "require": {
"php": "^8.3.0", "php": "^8.3.0",
"brianium/paratest": "^7.16.0", "brianium/paratest": "^7.16.1",
"nunomaduro/collision": "^8.8.3", "nunomaduro/collision": "^8.8.3",
"nunomaduro/termwind": "^2.3.3", "nunomaduro/termwind": "^2.3.3",
"pestphp/pest-plugin": "^4.0.0", "pestphp/pest-plugin": "^4.0.0",
"pestphp/pest-plugin-arch": "^4.0.0", "pestphp/pest-plugin-arch": "^4.0.0",
"pestphp/pest-plugin-mutate": "^4.0.1", "pestphp/pest-plugin-mutate": "^4.0.1",
"pestphp/pest-plugin-profanity": "^4.2.1", "pestphp/pest-plugin-profanity": "^4.2.1",
"phpunit/phpunit": "^12.5.4", "phpunit/phpunit": "^12.5.8",
"symfony/process": "^7.4.3|^8.0.0" "symfony/process": "^7.4.4|^8.0.0"
}, },
"conflict": { "conflict": {
"filp/whoops": "<2.18.3", "filp/whoops": "<2.18.3",
"phpunit/phpunit": ">12.5.4", "phpunit/phpunit": ">12.5.8",
"sebastian/exporter": "<7.0.0", "sebastian/exporter": "<7.0.0",
"webmozart/assert": "<1.11.0" "webmozart/assert": "<1.11.0"
}, },
@ -56,7 +56,7 @@
}, },
"require-dev": { "require-dev": {
"pestphp/pest-dev-tools": "^4.0.0", "pestphp/pest-dev-tools": "^4.0.0",
"pestphp/pest-plugin-browser": "^4.1.1", "pestphp/pest-plugin-browser": "^4.2.1",
"pestphp/pest-plugin-type-coverage": "^4.0.3", "pestphp/pest-plugin-type-coverage": "^4.0.3",
"psy/psysh": "^0.12.18" "psy/psysh": "^0.12.18"
}, },

View File

@ -8,6 +8,8 @@ use Closure;
/** /**
* @internal * @internal
*
* @template T of object
*/ */
trait Extendable trait Extendable
{ {
@ -20,6 +22,8 @@ trait Extendable
/** /**
* Register a new extend. * Register a new extend.
*
* @param-closure-this T $extend
*/ */
public function extend(string $name, Closure $extend): void public function extend(string $name, Closure $extend): void
{ {

View File

@ -52,7 +52,9 @@ use ReflectionProperty;
*/ */
final class Expectation final class Expectation
{ {
/** @use Extendable<self<TValue>> */
use Extendable; use Extendable;
use Pipeable; use Pipeable;
use Retrievable; use Retrievable;

View File

@ -6,7 +6,7 @@ namespace Pest;
function version(): string function version(): string
{ {
return '4.3.1'; return '4.3.2';
} }
function testDirectory(string $file = ''): string function testDirectory(string $file = ''): string

View File

@ -46,6 +46,7 @@ final readonly class HigherOrderCallables
*/ */
public function and(mixed $value): Expectation public function and(mixed $value): Expectation
{ {
// @phpstan-ignore-next-line
return $this->expect($value); return $this->expect($value);
} }

View File

@ -79,7 +79,7 @@ final class Str
return $subject; return $subject;
} }
return substr($subject, 0, $pos); return mb_substr($subject, 0, $pos);
} }
/** /**

View File

@ -1,5 +1,5 @@
Pest Testing Framework 4.3.1. Pest Testing Framework 4.3.2.
USAGE: pest <file> [options] USAGE: pest <file> [options]

View File

@ -1,3 +1,3 @@
Pest Testing Framework 4.3.1. Pest Testing Framework 4.3.2.

View File

@ -1,5 +1,5 @@
##teamcity[testSuiteStarted name='Tests/tests/SuccessOnly' locationHint='pest_qn://tests/.tests/SuccessOnly.php' flowId='1234'] ##teamcity[testSuiteStarted name='Tests/tests/SuccessOnly' locationHint='pest_qn://tests/.tests/SuccessOnly.php' flowId='1234']
##teamcity[testCount count='3' flowId='1234'] ##teamcity[testCount count='4' flowId='1234']
##teamcity[testStarted name='it can pass with comparison' locationHint='pest_qn://tests/.tests/SuccessOnly.php::it can pass with comparison' flowId='1234'] ##teamcity[testStarted name='it can pass with comparison' locationHint='pest_qn://tests/.tests/SuccessOnly.php::it can pass with comparison' flowId='1234']
##teamcity[testFinished name='it can pass with comparison' duration='100000' flowId='1234'] ##teamcity[testFinished name='it can pass with comparison' duration='100000' flowId='1234']
##teamcity[testStarted name='can also pass' locationHint='pest_qn://tests/.tests/SuccessOnly.php::can also pass' flowId='1234'] ##teamcity[testStarted name='can also pass' locationHint='pest_qn://tests/.tests/SuccessOnly.php::can also pass' flowId='1234']
@ -8,8 +8,12 @@
##teamcity[testStarted name='can pass with dataset with data set "(true)"' locationHint='pest_qn://tests/.tests/SuccessOnly.php::can pass with dataset with data set "(true)"' flowId='1234'] ##teamcity[testStarted name='can pass with dataset with data set "(true)"' locationHint='pest_qn://tests/.tests/SuccessOnly.php::can pass with dataset with data set "(true)"' flowId='1234']
##teamcity[testFinished name='can pass with dataset with data set "(true)"' duration='100000' flowId='1234'] ##teamcity[testFinished name='can pass with dataset with data set "(true)"' duration='100000' flowId='1234']
##teamcity[testSuiteFinished name='can pass with dataset' flowId='1234'] ##teamcity[testSuiteFinished name='can pass with dataset' flowId='1234']
##teamcity[testSuiteStarted name='`block` → can pass with dataset in describe block' locationHint='pest_qn://tests/.tests/SuccessOnly.php::`block` → can pass with dataset in describe block' flowId='1234']
##teamcity[testStarted name='`block` → can pass with dataset in describe block with data set "(1)"' locationHint='pest_qn://tests/.tests/SuccessOnly.php::`block` → can pass with dataset in describe block with data set "(1)"' flowId='1234']
##teamcity[testFinished name='`block` → can pass with dataset in describe block with data set "(1)"' duration='100000' flowId='1234']
##teamcity[testSuiteFinished name='`block` → can pass with dataset in describe block' flowId='1234']
##teamcity[testSuiteFinished name='Tests/tests/SuccessOnly' flowId='1234'] ##teamcity[testSuiteFinished name='Tests/tests/SuccessOnly' flowId='1234']
Tests: 3 passed (3 assertions) Tests: 4 passed (4 assertions)
Duration: 1.00s Duration: 1.00s

View File

@ -13,3 +13,9 @@ test('can also pass', function () {
test('can pass with dataset', function ($value) { test('can pass with dataset', function ($value) {
expect($value)->toEqual(true); expect($value)->toEqual(true);
})->with([true]); })->with([true]);
describe('block', function () {
test('can pass with dataset in describe block', function ($number) {
expect($number)->toBeInt();
})->with([1]);
});

View File

@ -36,8 +36,8 @@ test('junit output', function () use ($normalizedPath, $run) {
expect($result['testsuite']['@attributes']) expect($result['testsuite']['@attributes'])
->name->toBe('Tests\tests\SuccessOnly') ->name->toBe('Tests\tests\SuccessOnly')
->file->toBe($normalizedPath('tests/.tests/SuccessOnly.php')) ->file->toBe($normalizedPath('tests/.tests/SuccessOnly.php'))
->tests->toBe('3') ->tests->toBe('4')
->assertions->toBe('3') ->assertions->toBe('4')
->errors->toBe('0') ->errors->toBe('0')
->failures->toBe('0') ->failures->toBe('0')
->skipped->toBe('0'); ->skipped->toBe('0');