mirror of
https://github.com/pestphp/pest.git
synced 2026-03-06 15:57:21 +01:00
Compare commits
86 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 9688b83a3d | |||
| 675372c794 | |||
| c18636b3d5 | |||
| 145294a4a3 | |||
| c2cabaeae6 | |||
| 918a8fc169 | |||
| 5d32dd0641 | |||
| 982353fb38 | |||
| 2eefa8b88d | |||
| 787d5492ac | |||
| 06a0bd9b0b | |||
| 91afc81222 | |||
| 179d46ce97 | |||
| fa2bc1e536 | |||
| eaeb133c77 | |||
| cf57ea1f94 | |||
| 0b7f4f2384 | |||
| 2903a7e621 | |||
| b8964375c7 | |||
| bdcb883829 | |||
| 8a7e7f39ef | |||
| 67f217852c | |||
| 1bad148487 | |||
| e24f137b8e | |||
| 6d9189f3f5 | |||
| 6968094e2b | |||
| 9510d4a2f9 | |||
| cd2eb3504b | |||
| 7c639cdbbd | |||
| 1513ede73b | |||
| 8c65197881 | |||
| a6cd83665c | |||
| 0c57142c03 | |||
| 3f65af9fdf | |||
| 42d89814e3 | |||
| 1e3156a5b6 | |||
| 97713c0832 | |||
| 62b0e3c9df | |||
| 647de2f1cf | |||
| 0a7bff0d24 | |||
| 7618434580 | |||
| 1e0bb88b73 | |||
| 83b76d7c2e | |||
| 5a870b3940 | |||
| 1115c64186 | |||
| e38a271ca2 | |||
| 43703ab40a | |||
| 86452765a4 | |||
| b8a1b7e5cc | |||
| 5fe79d9c18 | |||
| 2744da4292 | |||
| 87f4e5e7b3 | |||
| bb3decf3cc | |||
| 4e2987d438 | |||
| a25158bce8 | |||
| 49e77b1d4c | |||
| 989e43d1a0 | |||
| 7cd42aafd8 | |||
| 48a1de273f | |||
| 970e16e949 | |||
| 432ff221c6 | |||
| a55da85dd2 | |||
| f291cd1603 | |||
| 5de0c2254a | |||
| b98ce0ced3 | |||
| 28772c2609 | |||
| 452ffaf8df | |||
| e8338405b5 | |||
| 1b014e4b18 | |||
| 034715e8b1 | |||
| 09eff785c4 | |||
| 22cc7805d7 | |||
| 669dc0da71 | |||
| 689da4ed4e | |||
| 2f15861b0d | |||
| 0d50d35b5e | |||
| ce61ced8e1 | |||
| 7227d24611 | |||
| 45f16484d5 | |||
| b16e8650da | |||
| c2f30e0148 | |||
| 47ce45de56 | |||
| 32881774d2 | |||
| ea72461f1b | |||
| 49f15521e0 | |||
| 95c5394b66 |
7
.github/workflows/tests.yml
vendored
7
.github/workflows/tests.yml
vendored
@ -13,8 +13,8 @@ jobs:
|
|||||||
fail-fast: true
|
fail-fast: true
|
||||||
matrix:
|
matrix:
|
||||||
os: [ubuntu-latest, macos-latest, windows-latest]
|
os: [ubuntu-latest, macos-latest, windows-latest]
|
||||||
symfony: ['7.0']
|
symfony: ['7.1']
|
||||||
php: ['8.2', '8.3']
|
php: ['8.2', '8.3', '8.4']
|
||||||
dependency_version: [prefer-lowest, prefer-stable]
|
dependency_version: [prefer-lowest, prefer-stable]
|
||||||
|
|
||||||
name: PHP ${{ matrix.php }} - Symfony ^${{ matrix.symfony }} - ${{ matrix.os }} - ${{ matrix.dependency_version }}
|
name: PHP ${{ matrix.php }} - Symfony ^${{ matrix.symfony }} - ${{ matrix.os }} - ${{ matrix.dependency_version }}
|
||||||
@ -36,7 +36,8 @@ jobs:
|
|||||||
echo "::add-matcher::${{ runner.tool_cache }}/phpunit.json"
|
echo "::add-matcher::${{ runner.tool_cache }}/phpunit.json"
|
||||||
|
|
||||||
- name: Install PHP dependencies
|
- name: Install PHP dependencies
|
||||||
run: composer update --${{ matrix.dependency_version }} --no-interaction --no-progress --ansi --with="symfony/console:~${{ matrix.symfony }}"
|
shell: bash
|
||||||
|
run: composer update --${{ matrix.dependency_version }} --no-interaction --no-progress --ansi --with="symfony/console:^${{ matrix.symfony }}"
|
||||||
|
|
||||||
- name: Unit Tests
|
- name: Unit Tests
|
||||||
run: composer test:unit
|
run: composer test:unit
|
||||||
|
|||||||
2
.gitignore
vendored
2
.gitignore
vendored
@ -12,3 +12,5 @@ coverage.xml
|
|||||||
*.swp
|
*.swp
|
||||||
*.swo
|
*.swo
|
||||||
.vscode/
|
.vscode/
|
||||||
|
.STREAM.md
|
||||||
|
|
||||||
|
|||||||
@ -42,7 +42,7 @@ composer test
|
|||||||
|
|
||||||
Check types:
|
Check types:
|
||||||
```bash
|
```bash
|
||||||
composer test:types
|
composer test:type:check
|
||||||
```
|
```
|
||||||
|
|
||||||
Unit tests:
|
Unit tests:
|
||||||
|
|||||||
@ -1,7 +1,7 @@
|
|||||||
<p align="center">
|
<p align="center">
|
||||||
<img src="https://raw.githubusercontent.com/pestphp/art/master/v3/banner.png" width="600" alt="PEST">
|
<img src="https://raw.githubusercontent.com/pestphp/art/master/v3/banner.png" width="600" alt="PEST">
|
||||||
<p align="center">
|
<p align="center">
|
||||||
<a href="https://github.com/pestphp/pest/actions"><img alt="GitHub Workflow Status (master)" src="https://img.shields.io/github/actions/workflow/status/pestphp/pest/tests.yml?branch=2.x&label=Tests%202.x"></a>
|
<a href="https://github.com/pestphp/pest/actions"><img alt="GitHub Workflow Status (master)" src="https://img.shields.io/github/actions/workflow/status/pestphp/pest/tests.yml?branch=3.x&label=Tests%203.x"></a>
|
||||||
<a href="https://packagist.org/packages/pestphp/pest"><img alt="Total Downloads" src="https://img.shields.io/packagist/dt/pestphp/pest"></a>
|
<a href="https://packagist.org/packages/pestphp/pest"><img alt="Total Downloads" src="https://img.shields.io/packagist/dt/pestphp/pest"></a>
|
||||||
<a href="https://packagist.org/packages/pestphp/pest"><img alt="Latest Version" src="https://img.shields.io/packagist/v/pestphp/pest"></a>
|
<a href="https://packagist.org/packages/pestphp/pest"><img alt="Latest Version" src="https://img.shields.io/packagist/v/pestphp/pest"></a>
|
||||||
<a href="https://packagist.org/packages/pestphp/pest"><img alt="License" src="https://img.shields.io/packagist/l/pestphp/pest"></a>
|
<a href="https://packagist.org/packages/pestphp/pest"><img alt="License" src="https://img.shields.io/packagist/l/pestphp/pest"></a>
|
||||||
@ -24,11 +24,10 @@ We cannot thank our sponsors enough for their incredible support in funding Pest
|
|||||||
|
|
||||||
### Platinum Sponsors
|
### Platinum Sponsors
|
||||||
|
|
||||||
|
- **[CodeRabbit](https://coderabbit.ai)**
|
||||||
- **[LaraJobs](https://larajobs.com)**
|
- **[LaraJobs](https://larajobs.com)**
|
||||||
- **[Brokerchooser](https://brokerchooser.com)**
|
- **[Brokerchooser](https://brokerchooser.com)**
|
||||||
- **[Forge](https://forge.laravel.com)**
|
- **[Forge](https://forge.laravel.com)**
|
||||||
- **[Spatie](https://spatie.be)**
|
|
||||||
- **[Worksome](https://www.worksome.com/)**
|
|
||||||
|
|
||||||
### Premium Sponsors
|
### Premium Sponsors
|
||||||
|
|
||||||
@ -38,6 +37,8 @@ We cannot thank our sponsors enough for their incredible support in funding Pest
|
|||||||
- [Laracasts](https://laracasts.com/?ref=pestphp)
|
- [Laracasts](https://laracasts.com/?ref=pestphp)
|
||||||
- [Localazy](https://localazy.com/?ref=pestphp)
|
- [Localazy](https://localazy.com/?ref=pestphp)
|
||||||
- [Route4Me](https://www.route4me.com/?ref=pestphp)
|
- [Route4Me](https://www.route4me.com/?ref=pestphp)
|
||||||
|
- [Spatie](https://spatie.be)
|
||||||
|
- [Worksome](https://www.worksome.com/)
|
||||||
- [Zapiet](https://www.zapiet.com/?ref=pestphp)
|
- [Zapiet](https://www.zapiet.com/?ref=pestphp)
|
||||||
|
|
||||||
Pest is an open-sourced software licensed under the **[MIT license](https://opensource.org/licenses/MIT)**.
|
Pest is an open-sourced software licensed under the **[MIT license](https://opensource.org/licenses/MIT)**.
|
||||||
|
|||||||
23
bin/pest
23
bin/pest
@ -1,5 +1,7 @@
|
|||||||
#!/usr/bin/env php
|
#!/usr/bin/env php
|
||||||
<?php declare(strict_types=1);
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
use Pest\Kernel;
|
use Pest\Kernel;
|
||||||
use Pest\Panic;
|
use Pest\Panic;
|
||||||
@ -37,7 +39,7 @@ use Symfony\Component\Console\Output\ConsoleOutput;
|
|||||||
|
|
||||||
if (str_contains($value, '--test-directory=')) {
|
if (str_contains($value, '--test-directory=')) {
|
||||||
unset($arguments[$key]);
|
unset($arguments[$key]);
|
||||||
} else if ($value === '--test-directory') {
|
} elseif ($value === '--test-directory') {
|
||||||
unset($arguments[$key]);
|
unset($arguments[$key]);
|
||||||
|
|
||||||
if (isset($arguments[$key + 1])) {
|
if (isset($arguments[$key + 1])) {
|
||||||
@ -62,7 +64,7 @@ use Symfony\Component\Console\Output\ConsoleOutput;
|
|||||||
|
|
||||||
if (str_contains($value, '--assignee=')) {
|
if (str_contains($value, '--assignee=')) {
|
||||||
unset($arguments[$key]);
|
unset($arguments[$key]);
|
||||||
} else if ($value === '--assignee') {
|
} elseif ($value === '--assignee') {
|
||||||
unset($arguments[$key]);
|
unset($arguments[$key]);
|
||||||
|
|
||||||
if (isset($arguments[$key + 1])) {
|
if (isset($arguments[$key + 1])) {
|
||||||
@ -72,7 +74,7 @@ use Symfony\Component\Console\Output\ConsoleOutput;
|
|||||||
|
|
||||||
if (str_contains($value, '--issue=')) {
|
if (str_contains($value, '--issue=')) {
|
||||||
unset($arguments[$key]);
|
unset($arguments[$key]);
|
||||||
} else if ($value === '--issue') {
|
} elseif ($value === '--issue') {
|
||||||
unset($arguments[$key]);
|
unset($arguments[$key]);
|
||||||
|
|
||||||
if (isset($arguments[$key + 1])) {
|
if (isset($arguments[$key + 1])) {
|
||||||
@ -82,7 +84,7 @@ use Symfony\Component\Console\Output\ConsoleOutput;
|
|||||||
|
|
||||||
if (str_contains($value, '--ticket=')) {
|
if (str_contains($value, '--ticket=')) {
|
||||||
unset($arguments[$key]);
|
unset($arguments[$key]);
|
||||||
} else if ($value === '--ticket') {
|
} elseif ($value === '--ticket') {
|
||||||
unset($arguments[$key]);
|
unset($arguments[$key]);
|
||||||
|
|
||||||
if (isset($arguments[$key + 1])) {
|
if (isset($arguments[$key + 1])) {
|
||||||
@ -92,7 +94,7 @@ use Symfony\Component\Console\Output\ConsoleOutput;
|
|||||||
|
|
||||||
if (str_contains($value, '--pr=')) {
|
if (str_contains($value, '--pr=')) {
|
||||||
unset($arguments[$key]);
|
unset($arguments[$key]);
|
||||||
} else if ($value === '--pr') {
|
} elseif ($value === '--pr') {
|
||||||
unset($arguments[$key]);
|
unset($arguments[$key]);
|
||||||
|
|
||||||
if (isset($arguments[$key + 1])) {
|
if (isset($arguments[$key + 1])) {
|
||||||
@ -102,7 +104,7 @@ use Symfony\Component\Console\Output\ConsoleOutput;
|
|||||||
|
|
||||||
if (str_contains($value, '--pull-request=')) {
|
if (str_contains($value, '--pull-request=')) {
|
||||||
unset($arguments[$key]);
|
unset($arguments[$key]);
|
||||||
} else if ($value === '--pull-request') {
|
} elseif ($value === '--pull-request') {
|
||||||
unset($arguments[$key]);
|
unset($arguments[$key]);
|
||||||
|
|
||||||
if (isset($arguments[$key + 1])) {
|
if (isset($arguments[$key + 1])) {
|
||||||
@ -117,7 +119,6 @@ use Symfony\Component\Console\Output\ConsoleOutput;
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Used when Pest is required using composer.
|
// Used when Pest is required using composer.
|
||||||
$vendorPath = dirname(__DIR__, 4).'/vendor/autoload.php';
|
$vendorPath = dirname(__DIR__, 4).'/vendor/autoload.php';
|
||||||
|
|
||||||
@ -134,7 +135,7 @@ use Symfony\Component\Console\Output\ConsoleOutput;
|
|||||||
|
|
||||||
// Get $rootPath based on $autoloadPath
|
// Get $rootPath based on $autoloadPath
|
||||||
$rootPath = dirname($autoloadPath, 2);
|
$rootPath = dirname($autoloadPath, 2);
|
||||||
$input = new ArgvInput();
|
$input = new ArgvInput;
|
||||||
|
|
||||||
$testSuite = TestSuite::getInstance(
|
$testSuite = TestSuite::getInstance(
|
||||||
$rootPath,
|
$rootPath,
|
||||||
@ -146,11 +147,11 @@ use Symfony\Component\Console\Output\ConsoleOutput;
|
|||||||
}
|
}
|
||||||
|
|
||||||
if ($todo) {
|
if ($todo) {
|
||||||
$testSuite->tests->addTestCaseMethodFilter(new TodoTestCaseFilter());
|
$testSuite->tests->addTestCaseMethodFilter(new TodoTestCaseFilter);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($notes) {
|
if ($notes) {
|
||||||
$testSuite->tests->addTestCaseMethodFilter(new NotesTestCaseFilter());
|
$testSuite->tests->addTestCaseMethodFilter(new NotesTestCaseFilter);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($assignee = $input->getParameterOption('--assignee')) {
|
if ($assignee = $input->getParameterOption('--assignee')) {
|
||||||
|
|||||||
@ -18,16 +18,17 @@
|
|||||||
],
|
],
|
||||||
"require": {
|
"require": {
|
||||||
"php": "^8.2.0",
|
"php": "^8.2.0",
|
||||||
"brianium/paratest": "^7.5.4",
|
"brianium/paratest": "^7.6.2",
|
||||||
"nunomaduro/collision": "^8.4.0",
|
"nunomaduro/collision": "^8.5.0",
|
||||||
"nunomaduro/termwind": "^2.1.0",
|
"nunomaduro/termwind": "^2.3.0",
|
||||||
"pestphp/pest-plugin": "^3.0.0",
|
"pestphp/pest-plugin": "^3.0.0",
|
||||||
"pestphp/pest-plugin-arch": "^3.0.0",
|
"pestphp/pest-plugin-arch": "^3.0.0",
|
||||||
"pestphp/pest-plugin-mutate": "^3.0.2",
|
"pestphp/pest-plugin-mutate": "^3.0.5",
|
||||||
"phpunit/phpunit": "^11.3.4"
|
"phpunit/phpunit": "^11.5.0"
|
||||||
},
|
},
|
||||||
"conflict": {
|
"conflict": {
|
||||||
"phpunit/phpunit": ">11.3.4",
|
"filp/whoops": "<2.16.0",
|
||||||
|
"phpunit/phpunit": ">11.5.0",
|
||||||
"sebastian/exporter": "<6.0.0",
|
"sebastian/exporter": "<6.0.0",
|
||||||
"webmozart/assert": "<1.11.0"
|
"webmozart/assert": "<1.11.0"
|
||||||
},
|
},
|
||||||
@ -52,9 +53,9 @@
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
"require-dev": {
|
"require-dev": {
|
||||||
"pestphp/pest-dev-tools": "^3.0.0",
|
"pestphp/pest-dev-tools": "^3.3.0",
|
||||||
"pestphp/pest-plugin-type-coverage": "^3.0.0",
|
"pestphp/pest-plugin-type-coverage": "^3.2.0",
|
||||||
"symfony/process": "^7.1.3"
|
"symfony/process": "^7.2.0"
|
||||||
},
|
},
|
||||||
"minimum-stability": "dev",
|
"minimum-stability": "dev",
|
||||||
"prefer-stable": true,
|
"prefer-stable": true,
|
||||||
|
|||||||
@ -68,7 +68,7 @@ final readonly class ThrowableBuilder
|
|||||||
$previous = self::from($previous);
|
$previous = self::from($previous);
|
||||||
}
|
}
|
||||||
|
|
||||||
$trace = Filter::getFilteredStacktrace($t);
|
$trace = Filter::stackTraceFromThrowableAsString($t);
|
||||||
|
|
||||||
if ($t instanceof RenderableOnCollisionEditor && $frame = $t->toCollisionEditor()) {
|
if ($t instanceof RenderableOnCollisionEditor && $frame = $t->toCollisionEditor()) {
|
||||||
$file = $frame->getFile();
|
$file = $frame->getFile();
|
||||||
|
|||||||
@ -1,6 +1,5 @@
|
|||||||
includes:
|
includes:
|
||||||
- vendor/phpstan/phpstan-strict-rules/rules.neon
|
- vendor/phpstan/phpstan-strict-rules/rules.neon
|
||||||
- vendor/ergebnis/phpstan-rules/rules.neon
|
|
||||||
- vendor/thecodingmachine/phpstan-strict-rules/phpstan-strict-rules.neon
|
- vendor/thecodingmachine/phpstan-strict-rules/phpstan-strict-rules.neon
|
||||||
|
|
||||||
parameters:
|
parameters:
|
||||||
@ -12,12 +11,4 @@ parameters:
|
|||||||
reportUnmatchedIgnoredErrors: true
|
reportUnmatchedIgnoredErrors: true
|
||||||
|
|
||||||
ignoreErrors:
|
ignoreErrors:
|
||||||
- "#has a nullable return type declaration.#"
|
|
||||||
- "#Language construct isset\\(\\) should not be used.#"
|
|
||||||
- "#is not allowed to extend#"
|
|
||||||
- "#is concrete, but does not have a Test suffix#"
|
|
||||||
- "#with a nullable type declaration#"
|
|
||||||
- "#type mixed is not subtype of native#"
|
- "#type mixed is not subtype of native#"
|
||||||
- "# with null as default value#"
|
|
||||||
- "#has parameter \\$closure with default value.#"
|
|
||||||
- "#has parameter \\$description with default value.#"
|
|
||||||
|
|||||||
@ -27,17 +27,20 @@ final class Laravel extends AbstractPreset
|
|||||||
->ignoring('App\Enums');
|
->ignoring('App\Enums');
|
||||||
|
|
||||||
$this->expectations[] = expect('App\Enums')
|
$this->expectations[] = expect('App\Enums')
|
||||||
->toBeEnums();
|
->toBeEnums()
|
||||||
|
->ignoring('App\Enums\Concerns');
|
||||||
|
|
||||||
$this->expectations[] = expect('App\Features')
|
$this->expectations[] = expect('App\Features')
|
||||||
->toBeClasses();
|
->toBeClasses()
|
||||||
|
->ignoring('App\Features\Concerns');
|
||||||
|
|
||||||
$this->expectations[] = expect('App\Features')
|
$this->expectations[] = expect('App\Features')
|
||||||
->toHaveMethod('resolve');
|
->toHaveMethod('resolve');
|
||||||
|
|
||||||
$this->expectations[] = expect('App\Exceptions')
|
$this->expectations[] = expect('App\Exceptions')
|
||||||
->classes()
|
->classes()
|
||||||
->toImplement('Throwable');
|
->toImplement('Throwable')
|
||||||
|
->ignoring('App\Exceptions\Handler');
|
||||||
|
|
||||||
$this->expectations[] = expect('App')
|
$this->expectations[] = expect('App')
|
||||||
->not->toImplement(Throwable::class)
|
->not->toImplement(Throwable::class)
|
||||||
@ -149,7 +152,7 @@ final class Laravel extends AbstractPreset
|
|||||||
->toOnlyBeUsedIn('App\Http');
|
->toOnlyBeUsedIn('App\Http');
|
||||||
|
|
||||||
$this->expectations[] = expect('App\Http\Controllers')
|
$this->expectations[] = expect('App\Http\Controllers')
|
||||||
->not->toHavePublicMethodsBesides(['__construct', '__invoke', 'index', 'show', 'create', 'store', 'edit', 'update', 'destroy']);
|
->not->toHavePublicMethodsBesides(['__construct', '__invoke', 'index', 'show', 'create', 'store', 'edit', 'update', 'destroy', 'middleware']);
|
||||||
|
|
||||||
$this->expectations[] = expect([
|
$this->expectations[] = expect([
|
||||||
'dd',
|
'dd',
|
||||||
@ -159,5 +162,9 @@ final class Laravel extends AbstractPreset
|
|||||||
'exit',
|
'exit',
|
||||||
'ray',
|
'ray',
|
||||||
])->not->toBeUsed();
|
])->not->toBeUsed();
|
||||||
|
|
||||||
|
$this->expectations[] = expect('App\Policies')
|
||||||
|
->classes()
|
||||||
|
->toHaveSuffix('Policy');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -21,6 +21,7 @@ final class Strict extends AbstractPreset
|
|||||||
fn (Expectation $namespace): ArchExpectation => $namespace->classes()->not->toHaveProtectedMethods(),
|
fn (Expectation $namespace): ArchExpectation => $namespace->classes()->not->toHaveProtectedMethods(),
|
||||||
fn (Expectation $namespace): ArchExpectation => $namespace->classes()->not->toBeAbstract(),
|
fn (Expectation $namespace): ArchExpectation => $namespace->classes()->not->toBeAbstract(),
|
||||||
fn (Expectation $namespace): ArchExpectation => $namespace->toUseStrictTypes(),
|
fn (Expectation $namespace): ArchExpectation => $namespace->toUseStrictTypes(),
|
||||||
|
fn (Expectation $namespace): ArchExpectation => $namespace->toUseStrictEquality(),
|
||||||
fn (Expectation $namespace): ArchExpectation => $namespace->classes()->toBeFinal(),
|
fn (Expectation $namespace): ArchExpectation => $namespace->classes()->toBeFinal(),
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|||||||
@ -18,14 +18,14 @@ final class BootOverrides implements Bootstrapper
|
|||||||
* @var array<string, string>
|
* @var array<string, string>
|
||||||
*/
|
*/
|
||||||
public const FILES = [
|
public const FILES = [
|
||||||
'c96b1cb57d7fc8e649f4c13a8abe418c2541bcfab194fb6702b99f777f52ee84' => 'Runner/Filter/NameFilterIterator.php',
|
'53c246e5f416a39817ac81124cdd64ea8403038d01d7a202e1ffa486fbdf3fa7' => 'Runner/Filter/NameFilterIterator.php',
|
||||||
'a4a43de01f641c6944ee83d963795a46d32b5206b5ab3bbc6cce76e67190acbf' => 'Runner/ResultCache/DefaultResultCache.php',
|
'a4a43de01f641c6944ee83d963795a46d32b5206b5ab3bbc6cce76e67190acbf' => 'Runner/ResultCache/DefaultResultCache.php',
|
||||||
'd0e81317889ad88c707db4b08a94cadee4c9010d05ff0a759f04e71af5efed89' => 'Runner/TestSuiteLoader.php',
|
'd0e81317889ad88c707db4b08a94cadee4c9010d05ff0a759f04e71af5efed89' => 'Runner/TestSuiteLoader.php',
|
||||||
'3bb609b0d3bf6dee8df8d6cd62a3c8ece823c4bb941eaaae39e3cb267171b9d2' => 'TextUI/Command/Commands/WarmCodeCoverageCacheCommand.php',
|
'3bb609b0d3bf6dee8df8d6cd62a3c8ece823c4bb941eaaae39e3cb267171b9d2' => 'TextUI/Command/Commands/WarmCodeCoverageCacheCommand.php',
|
||||||
'8abdad6413329c6fe0d7d44a8b9926e390af32c0b3123f3720bb9c5bbc6fbb7e' => 'TextUI/Output/Default/ProgressPrinter/Subscriber/TestSkippedSubscriber.php',
|
'8abdad6413329c6fe0d7d44a8b9926e390af32c0b3123f3720bb9c5bbc6fbb7e' => 'TextUI/Output/Default/ProgressPrinter/Subscriber/TestSkippedSubscriber.php',
|
||||||
'43883b7e5811886cf3731c8ed6304d5a77078d9731e1e505abc2da36bde19f3e' => 'TextUI/TestSuiteFilterProcessor.php',
|
'b4250fc3ffad5954624cb5e682fd940b874e8d3422fa1ee298bd7225e1aa5fc2' => 'TextUI/TestSuiteFilterProcessor.php',
|
||||||
'357d5cd7007f8559b26e1b8cdf43bb6fb15b51b79db981779da6f31b7ec39dad' => 'Event/Value/ThrowableBuilder.php',
|
'8cfcb4999af79463eca51a42058e502ea4ddc776cba5677bf2f8eb6093e21a5c' => 'Event/Value/ThrowableBuilder.php',
|
||||||
'01974a686eba69b5fbb87a904d936eae2176e39567616898c5b758db71d87a22' => 'Logging/JUnit/JunitXmlLogger.php',
|
'ede161507d4c9c27805f55a05a32c3bb528e53b6e1fc092bfafdb8207e0019e9' => 'Logging/JUnit/JunitXmlLogger.php',
|
||||||
];
|
];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@ -61,8 +61,10 @@ trait Testable
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* The test's describing, if any.
|
* The test's describing, if any.
|
||||||
|
*
|
||||||
|
* @var array<int, string>
|
||||||
*/
|
*/
|
||||||
public ?string $__describing = null;
|
public array $__describing = [];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Whether the test has ran or not.
|
* Whether the test has ran or not.
|
||||||
@ -116,7 +118,7 @@ trait Testable
|
|||||||
self::$__latestIssues = $method->issues;
|
self::$__latestIssues = $method->issues;
|
||||||
self::$__latestPrs = $method->prs;
|
self::$__latestPrs = $method->prs;
|
||||||
$this->__describing = $method->describing;
|
$this->__describing = $method->describing;
|
||||||
$this->__test = $method->getClosure($this);
|
$this->__test = $method->getClosure();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -240,6 +242,8 @@ trait Testable
|
|||||||
|
|
||||||
$method = TestSuite::getInstance()->tests->get(self::$__filename)->getMethod($this->name());
|
$method = TestSuite::getInstance()->tests->get(self::$__filename)->getMethod($this->name());
|
||||||
|
|
||||||
|
$method->setUp($this);
|
||||||
|
|
||||||
$description = $method->description;
|
$description = $method->description;
|
||||||
if ($this->dataName()) {
|
if ($this->dataName()) {
|
||||||
$description = str_contains((string) $description, ':dataset')
|
$description = str_contains((string) $description, ':dataset')
|
||||||
@ -298,6 +302,9 @@ trait Testable
|
|||||||
parent::tearDown();
|
parent::tearDown();
|
||||||
|
|
||||||
TestSuite::getInstance()->test = null;
|
TestSuite::getInstance()->test = null;
|
||||||
|
|
||||||
|
$method = TestSuite::getInstance()->tests->get(self::$__filename)->getMethod($this->name());
|
||||||
|
$method->tearDown($this);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -392,11 +399,12 @@ trait Testable
|
|||||||
fn (ReflectionParameter $reflectionParameter): string => $reflectionParameter->getName(),
|
fn (ReflectionParameter $reflectionParameter): string => $reflectionParameter->getName(),
|
||||||
array_filter($testReflection->getParameters(), fn (ReflectionParameter $reflectionParameter): bool => ! $reflectionParameter->isOptional()),
|
array_filter($testReflection->getParameters(), fn (ReflectionParameter $reflectionParameter): bool => ! $reflectionParameter->isOptional()),
|
||||||
);
|
);
|
||||||
|
|
||||||
if (array_diff($testParameterNames, $datasetParameterNames) === []) {
|
if (array_diff($testParameterNames, $datasetParameterNames) === []) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (isset($testParameterNames[0])
|
|
||||||
&& $suppliedParametersCount >= $requiredParametersCount) {
|
if (isset($testParameterNames[0]) && $suppliedParametersCount >= $requiredParametersCount) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -79,11 +79,11 @@ final readonly class Configuration
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the theme configuration.
|
* Gets the printer configuration.
|
||||||
*/
|
*/
|
||||||
public function theme(): Configuration\Theme
|
public function printer(): Configuration\Printer
|
||||||
{
|
{
|
||||||
return new Configuration\Theme;
|
return new Configuration\Printer;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@ -9,7 +9,7 @@ use NunoMaduro\Collision\Adapters\Phpunit\Printers\DefaultPrinter;
|
|||||||
/**
|
/**
|
||||||
* @internal
|
* @internal
|
||||||
*/
|
*/
|
||||||
final readonly class Theme
|
final readonly class Printer
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* Sets the theme to compact.
|
* Sets the theme to compact.
|
||||||
@ -89,7 +89,7 @@ final class Project
|
|||||||
{
|
{
|
||||||
$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";
|
$this->assignees = "https://{$namespace}.atlassian.net/secure/ViewProfile.jspa?name=%s";
|
||||||
|
|
||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -223,7 +223,7 @@ final class Expectation
|
|||||||
throw new BadMethodCallException('Expectation value is not iterable.');
|
throw new BadMethodCallException('Expectation value is not iterable.');
|
||||||
}
|
}
|
||||||
|
|
||||||
if (count($callbacks) == 0) {
|
if ($callbacks === []) {
|
||||||
throw new InvalidArgumentException('No sequence expectations defined.');
|
throw new InvalidArgumentException('No sequence expectations defined.');
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -264,7 +264,7 @@ final class Expectation
|
|||||||
$matched = false;
|
$matched = false;
|
||||||
|
|
||||||
foreach ($expressions as $key => $callback) {
|
foreach ($expressions as $key => $callback) {
|
||||||
if ($subject != $key) {
|
if ($subject != $key) { // @pest-arch-ignore-line
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -380,7 +380,7 @@ final class Expectation
|
|||||||
if (self::hasExtend($name)) {
|
if (self::hasExtend($name)) {
|
||||||
$extend = self::$extends[$name]->bindTo($this, Expectation::class);
|
$extend = self::$extends[$name]->bindTo($this, Expectation::class);
|
||||||
|
|
||||||
if ($extend != false) {
|
if ($extend != false) { // @pest-arch-ignore-line
|
||||||
return $extend;
|
return $extend;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -509,12 +509,25 @@ final class Expectation
|
|||||||
{
|
{
|
||||||
return Targeted::make(
|
return Targeted::make(
|
||||||
$this,
|
$this,
|
||||||
fn (ObjectDescription $object): bool => (bool) preg_match('/^<\?php\s+declare\(.*?strict_types\s?=\s?1.*?\);/', (string) file_get_contents($object->path)),
|
fn (ObjectDescription $object): bool => (bool) preg_match('/^<\?php\s*(\/\*[\s\S]*?\*\/|\/\/[^\r\n]*(?:\r?\n|$)|\s)*declare\s*\(\s*strict_types\s*=\s*1\s*\)\s*;/m', (string) file_get_contents($object->path)),
|
||||||
'to use strict types',
|
'to use strict types',
|
||||||
FileLineFinder::where(fn (string $line): bool => str_contains($line, '<?php')),
|
FileLineFinder::where(fn (string $line): bool => str_contains($line, '<?php')),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Asserts that the given expectation target uses strict equality.
|
||||||
|
*/
|
||||||
|
public function toUseStrictEquality(): ArchExpectation
|
||||||
|
{
|
||||||
|
return Targeted::make(
|
||||||
|
$this,
|
||||||
|
fn (ObjectDescription $object): bool => ! str_contains((string) file_get_contents($object->path), ' == ') && ! str_contains((string) file_get_contents($object->path), ' != '),
|
||||||
|
'to use strict equality',
|
||||||
|
FileLineFinder::where(fn (string $line): bool => str_contains($line, ' == ') || str_contains($line, ' != ')),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Asserts that the given expectation target is final.
|
* Asserts that the given expectation target is final.
|
||||||
*/
|
*/
|
||||||
|
|||||||
@ -152,6 +152,19 @@ final readonly class OppositeExpectation
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Asserts that the given expectation target does not use the strict equality operator.
|
||||||
|
*/
|
||||||
|
public function toUseStrictEquality(): ArchExpectation
|
||||||
|
{
|
||||||
|
return Targeted::make(
|
||||||
|
$this->original,
|
||||||
|
fn (ObjectDescription $object): bool => ! str_contains((string) file_get_contents($object->path), ' === ') && ! str_contains((string) file_get_contents($object->path), ' !== '),
|
||||||
|
'to use strict equality',
|
||||||
|
FileLineFinder::where(fn (string $line): bool => str_contains($line, ' === ') || str_contains($line, ' !== ')),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Asserts that the given expectation target is not final.
|
* Asserts that the given expectation target is not final.
|
||||||
*/
|
*/
|
||||||
|
|||||||
@ -166,7 +166,7 @@ final class TestCaseFactory
|
|||||||
}
|
}
|
||||||
PHP;
|
PHP;
|
||||||
|
|
||||||
eval($classCode); // @phpstan-ignore-line
|
eval($classCode);
|
||||||
} catch (ParseError $caught) {
|
} catch (ParseError $caught) {
|
||||||
throw new RuntimeException(sprintf(
|
throw new RuntimeException(sprintf(
|
||||||
"Unable to create test case for test file at %s. \n %s",
|
"Unable to create test case for test file at %s. \n %s",
|
||||||
|
|||||||
@ -31,8 +31,10 @@ final class TestCaseMethodFactory
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* The test's describing, if any.
|
* The test's describing, if any.
|
||||||
|
*
|
||||||
|
* @var array<int, string>
|
||||||
*/
|
*/
|
||||||
public ?string $describing = null;
|
public array $describing = [];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The test's description, if any.
|
* The test's description, if any.
|
||||||
@ -118,9 +120,9 @@ final class TestCaseMethodFactory
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates the test's closure.
|
* Sets the test's hooks, and runs any proxy to the test case.
|
||||||
*/
|
*/
|
||||||
public function getClosure(TestCase $concrete): Closure
|
public function setUp(TestCase $concrete): void
|
||||||
{
|
{
|
||||||
$concrete::flush(); // @phpstan-ignore-line
|
$concrete::flush(); // @phpstan-ignore-line
|
||||||
|
|
||||||
@ -128,14 +130,29 @@ final class TestCaseMethodFactory
|
|||||||
throw ShouldNotHappen::fromMessage('Description can not be empty.');
|
throw ShouldNotHappen::fromMessage('Description can not be empty.');
|
||||||
}
|
}
|
||||||
|
|
||||||
$closure = $this->closure;
|
|
||||||
|
|
||||||
$testCase = TestSuite::getInstance()->tests->get($this->filename);
|
$testCase = TestSuite::getInstance()->tests->get($this->filename);
|
||||||
|
|
||||||
assert($testCase instanceof TestCaseFactory);
|
assert($testCase instanceof TestCaseFactory);
|
||||||
$testCase->factoryProxies->proxy($concrete);
|
$testCase->factoryProxies->proxy($concrete);
|
||||||
$this->factoryProxies->proxy($concrete);
|
$this->factoryProxies->proxy($concrete);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Flushes the test case.
|
||||||
|
*/
|
||||||
|
public function tearDown(TestCase $concrete): void
|
||||||
|
{
|
||||||
|
$concrete::flush(); // @phpstan-ignore-line
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates the test's closure.
|
||||||
|
*/
|
||||||
|
public function getClosure(): Closure
|
||||||
|
{
|
||||||
|
$closure = $this->closure;
|
||||||
|
$testCase = TestSuite::getInstance()->tests->get($this->filename);
|
||||||
|
assert($testCase instanceof TestCaseFactory);
|
||||||
$method = $this;
|
$method = $this;
|
||||||
|
|
||||||
return function (...$arguments) use ($testCase, $method, $closure): mixed { // @phpstan-ignore-line
|
return function (...$arguments) use ($testCase, $method, $closure): mixed { // @phpstan-ignore-line
|
||||||
@ -186,7 +203,7 @@ final class TestCaseMethodFactory
|
|||||||
];
|
];
|
||||||
|
|
||||||
foreach ($this->depends as $depend) {
|
foreach ($this->depends as $depend) {
|
||||||
$depend = Str::evaluable($this->describing !== null ? Str::describe($this->describing, $depend) : $depend);
|
$depend = Str::evaluable($this->describing === [] ? $depend : Str::describe($this->describing, $depend));
|
||||||
|
|
||||||
$this->attributes[] = new Attribute(
|
$this->attributes[] = new Attribute(
|
||||||
\PHPUnit\Framework\Attributes\Depends::class,
|
\PHPUnit\Framework\Attributes\Depends::class,
|
||||||
@ -209,10 +226,8 @@ final class TestCaseMethodFactory
|
|||||||
$attributesCode
|
$attributesCode
|
||||||
public function $methodName(...\$arguments)
|
public function $methodName(...\$arguments)
|
||||||
{
|
{
|
||||||
\$test = \Pest\TestSuite::getInstance()->tests->get(self::\$__filename)->getMethod(\$this->name())->getClosure(\$this);
|
|
||||||
|
|
||||||
return \$this->__runTest(
|
return \$this->__runTest(
|
||||||
\$test,
|
\$this->__test,
|
||||||
...\$arguments,
|
...\$arguments,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -43,7 +43,7 @@ if (! function_exists('beforeAll')) {
|
|||||||
*/
|
*/
|
||||||
function beforeAll(Closure $closure): void
|
function beforeAll(Closure $closure): void
|
||||||
{
|
{
|
||||||
if (! is_null(DescribeCall::describing())) {
|
if (DescribeCall::describing() !== []) {
|
||||||
$filename = Backtrace::file();
|
$filename = Backtrace::file();
|
||||||
|
|
||||||
throw new BeforeAllWithinDescribe($filename);
|
throw new BeforeAllWithinDescribe($filename);
|
||||||
@ -205,7 +205,7 @@ if (! function_exists('afterAll')) {
|
|||||||
*/
|
*/
|
||||||
function afterAll(Closure $closure): void
|
function afterAll(Closure $closure): void
|
||||||
{
|
{
|
||||||
if (! is_null(DescribeCall::describing())) {
|
if (DescribeCall::describing() !== []) {
|
||||||
$filename = Backtrace::file();
|
$filename = Backtrace::file();
|
||||||
|
|
||||||
throw new AfterAllWithinDescribe($filename);
|
throw new AfterAllWithinDescribe($filename);
|
||||||
@ -217,7 +217,7 @@ if (! function_exists('afterAll')) {
|
|||||||
|
|
||||||
if (! function_exists('covers')) {
|
if (! function_exists('covers')) {
|
||||||
/**
|
/**
|
||||||
* Specifies which classes, or functions, a test method covers.
|
* Specifies which classes, or functions, a test case covers.
|
||||||
*
|
*
|
||||||
* @param array<int, string>|string $classesOrFunctions
|
* @param array<int, string>|string $classesOrFunctions
|
||||||
*/
|
*/
|
||||||
@ -243,3 +243,38 @@ if (! function_exists('covers')) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (! function_exists('mutates')) {
|
||||||
|
/**
|
||||||
|
* Specifies which classes, enums, or traits a test case mutates.
|
||||||
|
*
|
||||||
|
* @param array<int, string>|string $targets
|
||||||
|
*/
|
||||||
|
function mutates(array|string ...$targets): void
|
||||||
|
{
|
||||||
|
$filename = Backtrace::file();
|
||||||
|
|
||||||
|
$beforeEachCall = (new BeforeEachCall(TestSuite::getInstance(), $filename));
|
||||||
|
$beforeEachCall->group('__pest_mutate_only');
|
||||||
|
|
||||||
|
/** @var MutationTestRunner $runner */
|
||||||
|
$runner = Container::getInstance()->get(MutationTestRunner::class);
|
||||||
|
/** @var \Pest\Mutate\Repositories\ConfigurationRepository $configurationRepository */
|
||||||
|
$configurationRepository = Container::getInstance()->get(ConfigurationRepository::class);
|
||||||
|
$everything = $configurationRepository->cliConfiguration->toArray()['everything'] ?? false;
|
||||||
|
$classes = $configurationRepository->cliConfiguration->toArray()['classes'] ?? false;
|
||||||
|
$paths = $configurationRepository->cliConfiguration->toArray()['paths'] ?? false;
|
||||||
|
|
||||||
|
if ($runner->isEnabled() && ! $everything && ! is_array($classes) && ! is_array($paths)) {
|
||||||
|
$beforeEachCall->only('__pest_mutate_only');
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @var ConfigurationRepository $configurationRepository */
|
||||||
|
$configurationRepository = Container::getInstance()->get(ConfigurationRepository::class);
|
||||||
|
$paths = $configurationRepository->cliConfiguration->toArray()['paths'] ?? false;
|
||||||
|
|
||||||
|
if (! is_array($paths)) {
|
||||||
|
$configurationRepository->globalConfiguration('default')->class(...$targets); // @phpstan-ignore-line
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@ -40,7 +40,7 @@ final class KernelDump
|
|||||||
*/
|
*/
|
||||||
public function disable(): void
|
public function disable(): void
|
||||||
{
|
{
|
||||||
@ob_clean(); // @phpstan-ignore-line
|
@ob_clean();
|
||||||
|
|
||||||
if ($this->buffer !== '') {
|
if ($this->buffer !== '') {
|
||||||
$this->flush();
|
$this->flush();
|
||||||
|
|||||||
@ -18,6 +18,7 @@ use PHPUnit\Event\Test\Failed;
|
|||||||
use PHPUnit\Event\Test\MarkedIncomplete;
|
use PHPUnit\Event\Test\MarkedIncomplete;
|
||||||
use PHPUnit\Event\Test\Skipped;
|
use PHPUnit\Event\Test\Skipped;
|
||||||
use PHPUnit\Event\TestSuite\TestSuite;
|
use PHPUnit\Event\TestSuite\TestSuite;
|
||||||
|
use PHPUnit\Event\TestSuite\TestSuiteForTestMethodWithDataProvider;
|
||||||
use PHPUnit\Framework\Exception as FrameworkException;
|
use PHPUnit\Framework\Exception as FrameworkException;
|
||||||
use PHPUnit\TestRunner\TestResult\TestResult as PhpUnitTestResult;
|
use PHPUnit\TestRunner\TestResult\TestResult as PhpUnitTestResult;
|
||||||
|
|
||||||
@ -147,6 +148,13 @@ final readonly class Converter
|
|||||||
*/
|
*/
|
||||||
public function getTestSuiteName(TestSuite $testSuite): string
|
public function getTestSuiteName(TestSuite $testSuite): string
|
||||||
{
|
{
|
||||||
|
if ($testSuite instanceof TestSuiteForTestMethodWithDataProvider) {
|
||||||
|
$firstTest = $this->getFirstTest($testSuite);
|
||||||
|
if ($firstTest instanceof \PHPUnit\Event\Code\TestMethod) {
|
||||||
|
return $this->getTestMethodNameWithoutDatasetSuffix($firstTest);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
$name = $testSuite->name();
|
$name = $testSuite->name();
|
||||||
|
|
||||||
if (! str_starts_with($name, self::PREFIX)) {
|
if (! str_starts_with($name, self::PREFIX)) {
|
||||||
@ -168,6 +176,35 @@ final readonly class Converter
|
|||||||
* Gets the test suite location.
|
* Gets the test suite location.
|
||||||
*/
|
*/
|
||||||
public function getTestSuiteLocation(TestSuite $testSuite): ?string
|
public function getTestSuiteLocation(TestSuite $testSuite): ?string
|
||||||
|
{
|
||||||
|
$firstTest = $this->getFirstTest($testSuite);
|
||||||
|
if (! $firstTest instanceof \PHPUnit\Event\Code\TestMethod) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
$path = $firstTest->testDox()->prettifiedClassName();
|
||||||
|
$classRelativePath = $this->toRelativePath($path);
|
||||||
|
|
||||||
|
if ($testSuite instanceof TestSuiteForTestMethodWithDataProvider) {
|
||||||
|
$methodName = $this->getTestMethodNameWithoutDatasetSuffix($firstTest);
|
||||||
|
|
||||||
|
return "$classRelativePath::$methodName";
|
||||||
|
}
|
||||||
|
|
||||||
|
return $classRelativePath;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the prettified test method name without dataset-related suffix.
|
||||||
|
*/
|
||||||
|
private function getTestMethodNameWithoutDatasetSuffix(TestMethod $testMethod): string
|
||||||
|
{
|
||||||
|
return Str::beforeLast($testMethod->testDox()->prettifiedMethodName(), ' with data set ');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the first test from the test suite.
|
||||||
|
*/
|
||||||
|
private function getFirstTest(TestSuite $testSuite): ?TestMethod
|
||||||
{
|
{
|
||||||
$tests = $testSuite->tests()->asArray();
|
$tests = $testSuite->tests()->asArray();
|
||||||
|
|
||||||
@ -181,9 +218,7 @@ final readonly class Converter
|
|||||||
throw ShouldNotHappen::fromMessage('Not an instance of TestMethod');
|
throw ShouldNotHappen::fromMessage('Not an instance of TestMethod');
|
||||||
}
|
}
|
||||||
|
|
||||||
$path = $firstTest->testDox()->prettifiedClassName();
|
return $firstTest;
|
||||||
|
|
||||||
return $this->toRelativePath($path);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@ -38,7 +38,7 @@ final class ServiceMessage
|
|||||||
{
|
{
|
||||||
return new self('testSuiteStarted', [
|
return new self('testSuiteStarted', [
|
||||||
'name' => $name,
|
'name' => $name,
|
||||||
'locationHint' => $location === null ? null : "file://$location",
|
'locationHint' => $location === null ? null : "pest_qn://$location",
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -6,6 +6,7 @@ namespace Pest\PendingCalls;
|
|||||||
|
|
||||||
use Closure;
|
use Closure;
|
||||||
use Pest\PendingCalls\Concerns\Describable;
|
use Pest\PendingCalls\Concerns\Describable;
|
||||||
|
use Pest\Support\Arr;
|
||||||
use Pest\Support\Backtrace;
|
use Pest\Support\Backtrace;
|
||||||
use Pest\Support\ChainableClosure;
|
use Pest\Support\ChainableClosure;
|
||||||
use Pest\Support\HigherOrderMessageCollection;
|
use Pest\Support\HigherOrderMessageCollection;
|
||||||
@ -54,8 +55,8 @@ final class AfterEachCall
|
|||||||
$proxies = $this->proxies;
|
$proxies = $this->proxies;
|
||||||
|
|
||||||
$afterEachTestCase = ChainableClosure::boundWhen(
|
$afterEachTestCase = ChainableClosure::boundWhen(
|
||||||
fn (): bool => is_null($describing) || $this->__describing === $describing,
|
fn (): bool => $describing === [] || in_array(Arr::last($describing), $this->__describing, true),
|
||||||
ChainableClosure::bound(fn () => $proxies->chain($this), $this->closure)->bindTo($this, self::class), // @phpstan-ignore-line
|
ChainableClosure::bound(fn () => $proxies->chain($this), $this->closure)->bindTo($this, self::class),
|
||||||
)->bindTo($this, self::class);
|
)->bindTo($this, self::class);
|
||||||
|
|
||||||
assert($afterEachTestCase instanceof Closure);
|
assert($afterEachTestCase instanceof Closure);
|
||||||
|
|||||||
@ -7,6 +7,7 @@ namespace Pest\PendingCalls;
|
|||||||
use Closure;
|
use Closure;
|
||||||
use Pest\Exceptions\AfterBeforeTestFunction;
|
use Pest\Exceptions\AfterBeforeTestFunction;
|
||||||
use Pest\PendingCalls\Concerns\Describable;
|
use Pest\PendingCalls\Concerns\Describable;
|
||||||
|
use Pest\Support\Arr;
|
||||||
use Pest\Support\Backtrace;
|
use Pest\Support\Backtrace;
|
||||||
use Pest\Support\ChainableClosure;
|
use Pest\Support\ChainableClosure;
|
||||||
use Pest\Support\HigherOrderMessageCollection;
|
use Pest\Support\HigherOrderMessageCollection;
|
||||||
@ -63,12 +64,12 @@ final class BeforeEachCall
|
|||||||
|
|
||||||
$beforeEachTestCall = function (TestCall $testCall) use ($describing): void {
|
$beforeEachTestCall = function (TestCall $testCall) use ($describing): void {
|
||||||
|
|
||||||
if ($this->describing !== null) {
|
if ($this->describing !== []) {
|
||||||
if ($describing !== $this->describing) {
|
if (Arr::last($describing) !== Arr::last($this->describing)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($describing !== $testCall->describing) {
|
if (! in_array(Arr::last($describing), $testCall->describing, true)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -77,8 +78,8 @@ final class BeforeEachCall
|
|||||||
};
|
};
|
||||||
|
|
||||||
$beforeEachTestCase = ChainableClosure::boundWhen(
|
$beforeEachTestCase = ChainableClosure::boundWhen(
|
||||||
fn (): bool => is_null($describing) || $this->__describing === $describing,
|
fn (): bool => $describing === [] || in_array(Arr::last($describing), $this->__describing, true),
|
||||||
ChainableClosure::bound(fn () => $testCaseProxies->chain($this), $this->closure)->bindTo($this, self::class), // @phpstan-ignore-line
|
ChainableClosure::bound(fn () => $testCaseProxies->chain($this), $this->closure)->bindTo($this, self::class),
|
||||||
)->bindTo($this, self::class);
|
)->bindTo($this, self::class);
|
||||||
|
|
||||||
assert($beforeEachTestCase instanceof Closure);
|
assert($beforeEachTestCase instanceof Closure);
|
||||||
@ -96,7 +97,7 @@ final class BeforeEachCall
|
|||||||
*/
|
*/
|
||||||
public function after(Closure $closure): self
|
public function after(Closure $closure): self
|
||||||
{
|
{
|
||||||
if ($this->describing === null) {
|
if ($this->describing === []) {
|
||||||
throw new AfterBeforeTestFunction($this->filename);
|
throw new AfterBeforeTestFunction($this->filename);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -11,11 +11,15 @@ trait Describable
|
|||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* Note: this is property is not used; however, it gets added automatically by rector php.
|
* Note: this is property is not used; however, it gets added automatically by rector php.
|
||||||
|
*
|
||||||
|
* @var array<int, string>
|
||||||
*/
|
*/
|
||||||
public string $__describing;
|
public array $__describing;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The describing of the test case.
|
* The describing of the test case.
|
||||||
|
*
|
||||||
|
* @var array<int, string>
|
||||||
*/
|
*/
|
||||||
public ?string $describing = null;
|
public array $describing = [];
|
||||||
}
|
}
|
||||||
|
|||||||
@ -15,8 +15,10 @@ final class DescribeCall
|
|||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* The current describe call.
|
* The current describe call.
|
||||||
|
*
|
||||||
|
* @var array<int, string>
|
||||||
*/
|
*/
|
||||||
private static ?string $describing = null;
|
private static array $describing = [];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The describe "before each" call.
|
* The describe "before each" call.
|
||||||
@ -37,8 +39,10 @@ final class DescribeCall
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* What is the current describing.
|
* What is the current describing.
|
||||||
|
*
|
||||||
|
* @return array<int, string>
|
||||||
*/
|
*/
|
||||||
public static function describing(): ?string
|
public static function describing(): array
|
||||||
{
|
{
|
||||||
return self::$describing;
|
return self::$describing;
|
||||||
}
|
}
|
||||||
@ -50,12 +54,12 @@ final class DescribeCall
|
|||||||
{
|
{
|
||||||
unset($this->currentBeforeEachCall);
|
unset($this->currentBeforeEachCall);
|
||||||
|
|
||||||
self::$describing = $this->description;
|
self::$describing[] = $this->description;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
($this->tests)();
|
($this->tests)();
|
||||||
} finally {
|
} finally {
|
||||||
self::$describing = null;
|
array_pop(self::$describing);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -71,7 +75,7 @@ final class DescribeCall
|
|||||||
if (! $this->currentBeforeEachCall instanceof \Pest\PendingCalls\BeforeEachCall) {
|
if (! $this->currentBeforeEachCall instanceof \Pest\PendingCalls\BeforeEachCall) {
|
||||||
$this->currentBeforeEachCall = new BeforeEachCall(TestSuite::getInstance(), $filename);
|
$this->currentBeforeEachCall = new BeforeEachCall(TestSuite::getInstance(), $filename);
|
||||||
|
|
||||||
$this->currentBeforeEachCall->describing = $this->description;
|
$this->currentBeforeEachCall->describing[] = $this->description;
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->currentBeforeEachCall->{$name}(...$arguments); // @phpstan-ignore-line
|
$this->currentBeforeEachCall->{$name}(...$arguments); // @phpstan-ignore-line
|
||||||
|
|||||||
@ -5,6 +5,7 @@ declare(strict_types=1);
|
|||||||
namespace Pest\PendingCalls;
|
namespace Pest\PendingCalls;
|
||||||
|
|
||||||
use Closure;
|
use Closure;
|
||||||
|
use Pest\Concerns\Testable;
|
||||||
use Pest\Exceptions\InvalidArgumentException;
|
use Pest\Exceptions\InvalidArgumentException;
|
||||||
use Pest\Exceptions\TestDescriptionMissing;
|
use Pest\Exceptions\TestDescriptionMissing;
|
||||||
use Pest\Factories\Attribute;
|
use Pest\Factories\Attribute;
|
||||||
@ -25,9 +26,9 @@ use PHPUnit\Framework\TestCase;
|
|||||||
/**
|
/**
|
||||||
* @internal
|
* @internal
|
||||||
*
|
*
|
||||||
* @mixin HigherOrderCallables|TestCase
|
* @mixin HigherOrderCallables|TestCase|Testable
|
||||||
*/
|
*/
|
||||||
final class TestCall
|
final class TestCall // @phpstan-ignore-line
|
||||||
{
|
{
|
||||||
use Describable;
|
use Describable;
|
||||||
|
|
||||||
@ -75,7 +76,7 @@ final class TestCall
|
|||||||
throw new TestDescriptionMissing($this->filename);
|
throw new TestDescriptionMissing($this->filename);
|
||||||
}
|
}
|
||||||
|
|
||||||
$description = is_null($this->describing)
|
$description = $this->describing === []
|
||||||
? $this->description
|
? $this->description
|
||||||
: Str::describe($this->describing, $this->description);
|
: Str::describe($this->describing, $this->description);
|
||||||
|
|
||||||
@ -358,8 +359,8 @@ final class TestCall
|
|||||||
public function todo(// @phpstan-ignore-line
|
public function todo(// @phpstan-ignore-line
|
||||||
array|string|null $note = null,
|
array|string|null $note = null,
|
||||||
array|string|null $assignee = null,
|
array|string|null $assignee = null,
|
||||||
array|string|null $issue = null,
|
array|string|int|null $issue = null,
|
||||||
array|string|null $pr = null,
|
array|string|int|null $pr = null,
|
||||||
): self {
|
): self {
|
||||||
$this->skip('__TODO__');
|
$this->skip('__TODO__');
|
||||||
|
|
||||||
@ -390,8 +391,8 @@ final class TestCall
|
|||||||
public function wip(// @phpstan-ignore-line
|
public function wip(// @phpstan-ignore-line
|
||||||
array|string|null $note = null,
|
array|string|null $note = null,
|
||||||
array|string|null $assignee = null,
|
array|string|null $assignee = null,
|
||||||
array|string|null $issue = null,
|
array|string|int|null $issue = null,
|
||||||
array|string|null $pr = null,
|
array|string|int|null $pr = null,
|
||||||
): self {
|
): self {
|
||||||
if ($issue !== null) {
|
if ($issue !== null) {
|
||||||
$this->issue($issue);
|
$this->issue($issue);
|
||||||
@ -418,8 +419,8 @@ final class TestCall
|
|||||||
public function done(// @phpstan-ignore-line
|
public function done(// @phpstan-ignore-line
|
||||||
array|string|null $note = null,
|
array|string|null $note = null,
|
||||||
array|string|null $assignee = null,
|
array|string|null $assignee = null,
|
||||||
array|string|null $issue = null,
|
array|string|int|null $issue = null,
|
||||||
array|string|null $pr = null,
|
array|string|int|null $pr = null,
|
||||||
): self {
|
): self {
|
||||||
if ($issue !== null) {
|
if ($issue !== null) {
|
||||||
$this->issue($issue);
|
$this->issue($issue);
|
||||||
@ -682,7 +683,7 @@ final class TestCall
|
|||||||
throw new TestDescriptionMissing($this->filename);
|
throw new TestDescriptionMissing($this->filename);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (! is_null($this->describing)) {
|
if ($this->describing !== []) {
|
||||||
$this->testCaseMethod->describing = $this->describing;
|
$this->testCaseMethod->describing = $this->describing;
|
||||||
$this->testCaseMethod->description = Str::describe($this->describing, $this->description);
|
$this->testCaseMethod->description = Str::describe($this->describing, $this->description);
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@ -54,7 +54,7 @@ final class UsesCall
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @deprecated Use `pest()->theme()->compact()` instead.
|
* @deprecated Use `pest()->printer()->compact()` instead.
|
||||||
*/
|
*/
|
||||||
public function compact(): self
|
public function compact(): self
|
||||||
{
|
{
|
||||||
|
|||||||
@ -6,7 +6,7 @@ namespace Pest;
|
|||||||
|
|
||||||
function version(): string
|
function version(): string
|
||||||
{
|
{
|
||||||
return '3.0.1';
|
return '3.7.0';
|
||||||
}
|
}
|
||||||
|
|
||||||
function testDirectory(string $file = ''): string
|
function testDirectory(string $file = ''): string
|
||||||
|
|||||||
@ -27,6 +27,11 @@ final class Coverage implements AddsOutput, HandlesArguments
|
|||||||
*/
|
*/
|
||||||
private const MIN_OPTION = 'min';
|
private const MIN_OPTION = 'min';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
|
private const EXACTLY_OPTION = 'exactly';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Whether it should show the coverage or not.
|
* Whether it should show the coverage or not.
|
||||||
*/
|
*/
|
||||||
@ -37,6 +42,11 @@ final class Coverage implements AddsOutput, HandlesArguments
|
|||||||
*/
|
*/
|
||||||
public float $coverageMin = 0.0;
|
public float $coverageMin = 0.0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The exactly coverage.
|
||||||
|
*/
|
||||||
|
public ?float $coverageExactly = null;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a new Plugin instance.
|
* Creates a new Plugin instance.
|
||||||
*/
|
*/
|
||||||
@ -51,7 +61,7 @@ final class Coverage implements AddsOutput, HandlesArguments
|
|||||||
public function handleArguments(array $originals): array
|
public function handleArguments(array $originals): array
|
||||||
{
|
{
|
||||||
$arguments = [...[''], ...array_values(array_filter($originals, function (string $original): bool {
|
$arguments = [...[''], ...array_values(array_filter($originals, function (string $original): bool {
|
||||||
foreach ([self::COVERAGE_OPTION, self::MIN_OPTION] as $option) {
|
foreach ([self::COVERAGE_OPTION, self::MIN_OPTION, self::EXACTLY_OPTION] as $option) {
|
||||||
if ($original === sprintf('--%s', $option)) {
|
if ($original === sprintf('--%s', $option)) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -73,6 +83,7 @@ final class Coverage implements AddsOutput, HandlesArguments
|
|||||||
$inputs = [];
|
$inputs = [];
|
||||||
$inputs[] = new InputOption(self::COVERAGE_OPTION, null, InputOption::VALUE_NONE);
|
$inputs[] = new InputOption(self::COVERAGE_OPTION, null, InputOption::VALUE_NONE);
|
||||||
$inputs[] = new InputOption(self::MIN_OPTION, null, InputOption::VALUE_REQUIRED);
|
$inputs[] = new InputOption(self::MIN_OPTION, null, InputOption::VALUE_REQUIRED);
|
||||||
|
$inputs[] = new InputOption(self::EXACTLY_OPTION, null, InputOption::VALUE_REQUIRED);
|
||||||
|
|
||||||
$input = new ArgvInput($arguments, new InputDefinition($inputs));
|
$input = new ArgvInput($arguments, new InputDefinition($inputs));
|
||||||
if ((bool) $input->getOption(self::COVERAGE_OPTION)) {
|
if ((bool) $input->getOption(self::COVERAGE_OPTION)) {
|
||||||
@ -106,6 +117,13 @@ final class Coverage implements AddsOutput, HandlesArguments
|
|||||||
$this->coverageMin = (float) $minOption;
|
$this->coverageMin = (float) $minOption;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ($input->getOption(self::EXACTLY_OPTION) !== null) {
|
||||||
|
/** @var int|float $exactlyOption */
|
||||||
|
$exactlyOption = $input->getOption(self::EXACTLY_OPTION);
|
||||||
|
|
||||||
|
$this->coverageExactly = (float) $exactlyOption;
|
||||||
|
}
|
||||||
|
|
||||||
return $originals;
|
return $originals;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -127,10 +145,22 @@ final class Coverage implements AddsOutput, HandlesArguments
|
|||||||
}
|
}
|
||||||
|
|
||||||
$coverage = \Pest\Support\Coverage::report($this->output);
|
$coverage = \Pest\Support\Coverage::report($this->output);
|
||||||
|
|
||||||
$exitCode = (int) ($coverage < $this->coverageMin);
|
$exitCode = (int) ($coverage < $this->coverageMin);
|
||||||
|
|
||||||
if ($exitCode === 1) {
|
if ($exitCode === 0 && $this->coverageExactly !== null) {
|
||||||
|
$comparableCoverage = $this->computeComparableCoverage($coverage);
|
||||||
|
$comparableCoverageExactly = $this->computeComparableCoverage($this->coverageExactly);
|
||||||
|
|
||||||
|
$exitCode = $comparableCoverage === $comparableCoverageExactly ? 0 : 1;
|
||||||
|
|
||||||
|
if ($exitCode === 1) {
|
||||||
|
$this->output->writeln(sprintf(
|
||||||
|
"\n <fg=white;bg=red;options=bold> FAIL </> Code coverage not exactly <fg=white;options=bold> %s %%</>, currently <fg=red;options=bold> %s %%</>.",
|
||||||
|
number_format($this->coverageExactly, 1),
|
||||||
|
number_format(floor($coverage * 10) / 10, 1),
|
||||||
|
));
|
||||||
|
}
|
||||||
|
} elseif ($exitCode === 1) {
|
||||||
$this->output->writeln(sprintf(
|
$this->output->writeln(sprintf(
|
||||||
"\n <fg=white;bg=red;options=bold> FAIL </> Code coverage below expected <fg=white;options=bold> %s %%</>, currently <fg=red;options=bold> %s %%</>.",
|
"\n <fg=white;bg=red;options=bold> FAIL </> Code coverage below expected <fg=white;options=bold> %s %%</>, currently <fg=red;options=bold> %s %%</>.",
|
||||||
number_format($this->coverageMin, 1),
|
number_format($this->coverageMin, 1),
|
||||||
@ -143,4 +173,12 @@ final class Coverage implements AddsOutput, HandlesArguments
|
|||||||
|
|
||||||
return $exitCode;
|
return $exitCode;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Computes the comparable coverage to a percentage with one decimal.
|
||||||
|
*/
|
||||||
|
private function computeComparableCoverage(float $coverage): float
|
||||||
|
{
|
||||||
|
return floor($coverage * 10) / 10;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -122,6 +122,9 @@ final class WrapperRunner implements RunnerInterface
|
|||||||
$parameters = array_merge($parameters, $options->passthruPhp);
|
$parameters = array_merge($parameters, $options->passthruPhp);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** @var array<int, non-empty-string> $parameters */
|
||||||
|
$parameters = $this->handleLaravelHerd($parameters);
|
||||||
|
|
||||||
$parameters[] = $wrapper;
|
$parameters[] = $wrapper;
|
||||||
|
|
||||||
$this->parameters = $parameters;
|
$this->parameters = $parameters;
|
||||||
@ -153,6 +156,21 @@ final class WrapperRunner implements RunnerInterface
|
|||||||
return $this->complete($result);
|
return $this->complete($result);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handles Laravel Herd's debug and coverage modes.
|
||||||
|
*
|
||||||
|
* @param array<string> $parameters
|
||||||
|
* @return array<string>
|
||||||
|
*/
|
||||||
|
private function handleLaravelHerd(array $parameters): array
|
||||||
|
{
|
||||||
|
if (isset($_ENV['HERD_DEBUG_INI'])) {
|
||||||
|
return array_merge($parameters, ['-c', $_ENV['HERD_DEBUG_INI']]);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $parameters;
|
||||||
|
}
|
||||||
|
|
||||||
private function startWorkers(): void
|
private function startWorkers(): void
|
||||||
{
|
{
|
||||||
for ($token = 1; $token <= $this->options->processes; $token++) {
|
for ($token = 1; $token <= $this->options->processes; $token++) {
|
||||||
|
|||||||
@ -81,4 +81,14 @@ final class Arr
|
|||||||
|
|
||||||
return $results;
|
return $results;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the value of the last element or false for empty array
|
||||||
|
*
|
||||||
|
* @param array<array-key, mixed> $array
|
||||||
|
*/
|
||||||
|
public static function last(array $array): mixed
|
||||||
|
{
|
||||||
|
return end($array);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -20,13 +20,13 @@ final class Closure
|
|||||||
*/
|
*/
|
||||||
public static function bind(?BaseClosure $closure, ?object $newThis, object|string|null $newScope = 'static'): BaseClosure
|
public static function bind(?BaseClosure $closure, ?object $newThis, object|string|null $newScope = 'static'): BaseClosure
|
||||||
{
|
{
|
||||||
if ($closure == null) {
|
if (! $closure instanceof \Closure) {
|
||||||
throw ShouldNotHappen::fromMessage('Could not bind null closure.');
|
throw ShouldNotHappen::fromMessage('Could not bind null closure.');
|
||||||
}
|
}
|
||||||
|
|
||||||
$closure = BaseClosure::bind($closure, $newThis, $newScope);
|
$closure = BaseClosure::bind($closure, $newThis, $newScope);
|
||||||
|
|
||||||
if ($closure == false) {
|
if (! $closure instanceof \Closure) {
|
||||||
throw ShouldNotHappen::fromMessage('Could not bind closure.');
|
throw ShouldNotHappen::fromMessage('Could not bind closure.');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -103,10 +103,14 @@ final class Str
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a describe block as `$describeDescription` → `$testDescription` format.
|
* Creates a describe block as `$describeDescription` → `$testDescription` format.
|
||||||
|
*
|
||||||
|
* @param array<int, string> $describeDescriptions
|
||||||
*/
|
*/
|
||||||
public static function describe(string $describeDescription, string $testDescription): string
|
public static function describe(array $describeDescriptions, string $testDescription): string
|
||||||
{
|
{
|
||||||
return sprintf('`%s` → %s', $describeDescription, $testDescription);
|
$descriptionComponents = [...$describeDescriptions, $testDescription];
|
||||||
|
|
||||||
|
return sprintf(str_repeat('`%s` → ', count($describeDescriptions)).'%s', ...$descriptionComponents);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@ -1,5 +1,5 @@
|
|||||||
|
|
||||||
Pest Testing Framework 3.0.1.
|
Pest Testing Framework 3.7.0.
|
||||||
|
|
||||||
USAGE: pest <file> [options]
|
USAGE: pest <file> [options]
|
||||||
|
|
||||||
@ -35,6 +35,7 @@
|
|||||||
--exclude-group [name] ........... Exclude tests from the specified group(s)
|
--exclude-group [name] ........... Exclude tests from the specified group(s)
|
||||||
--covers [name] ................. Only run tests that intend to cover [name]
|
--covers [name] ................. Only run tests that intend to cover [name]
|
||||||
--uses [name] ..................... Only run tests that intend to use [name]
|
--uses [name] ..................... Only run tests that intend to use [name]
|
||||||
|
--requires-php-extension [name] Only run tests that require PHP extension [name]
|
||||||
--list-test-files ................................ List available test files
|
--list-test-files ................................ List available test files
|
||||||
--list-tests .......................................... List available tests
|
--list-tests .......................................... List available tests
|
||||||
--list-tests-xml [file] ................. List available tests in XML format
|
--list-tests-xml [file] ................. List available tests in XML format
|
||||||
|
|||||||
@ -15,7 +15,7 @@
|
|||||||
↓ todo on describe → should not fail
|
↓ todo on describe → should not fail
|
||||||
↓ todo on describe → should run
|
↓ todo on describe → should run
|
||||||
|
|
||||||
TODO Tests\Features\Todo - 7 todos
|
TODO Tests\Features\Todo - 28 todos
|
||||||
↓ something todo later
|
↓ something todo later
|
||||||
↓ something todo later chained
|
↓ something todo later chained
|
||||||
↓ something todo later chained and with function body
|
↓ something todo later chained and with function body
|
||||||
@ -24,6 +24,52 @@
|
|||||||
↓ it may have an associated PR #1
|
↓ it may have an associated PR #1
|
||||||
↓ it may have an associated note
|
↓ it may have an associated note
|
||||||
// a note
|
// a note
|
||||||
|
↓ todo on describe → todo block → nested inside todo block → it should not execute
|
||||||
|
↓ todo on describe → todo block → nested inside todo block → it should set the note
|
||||||
|
// hi
|
||||||
|
↓ todo on describe → todo block → describe with note → it should apply the note to a test without a todo
|
||||||
|
// describe note
|
||||||
|
↓ todo on describe → todo block → describe with note → it should apply the note to a test with a todo
|
||||||
|
// describe note
|
||||||
|
↓ todo on describe → todo block → describe with note → it should apply the note as well as the note from the test
|
||||||
|
// describe note
|
||||||
|
// test note
|
||||||
|
↓ todo on describe → todo block → describe with note → nested describe with note → it should apply all parent notes to a test without a todo
|
||||||
|
// describe note
|
||||||
|
// nested describe note
|
||||||
|
↓ todo on describe → todo block → describe with note → nested describe with note → it should apply all parent notes to a test with a todo
|
||||||
|
// describe note
|
||||||
|
// nested describe note
|
||||||
|
↓ todo on describe → todo block → describe with note → nested describe with note → it should apply all parent notes as well as the note from the test
|
||||||
|
// describe note
|
||||||
|
// nested describe note
|
||||||
|
// test note
|
||||||
|
↓ todo on describe → todo block → it should not execute
|
||||||
|
↓ todo on test after describe block
|
||||||
|
↓ todo with note on test after describe block
|
||||||
|
// test note
|
||||||
|
↓ todo on beforeEach → todo block → nested inside todo block → it should not execute
|
||||||
|
↓ todo on beforeEach → todo block → describe with note → it should apply the note to a test without a todo
|
||||||
|
// describe note
|
||||||
|
↓ todo on beforeEach → todo block → describe with note → it should apply the note to a test with a todo
|
||||||
|
// describe note
|
||||||
|
↓ todo on beforeEach → todo block → describe with note → it should apply the note as well as the note from the test
|
||||||
|
// describe note
|
||||||
|
// test note
|
||||||
|
↓ todo on beforeEach → todo block → describe with note → nested describe with note → it should apply all parent notes to a test without a todo
|
||||||
|
// describe note
|
||||||
|
// nested describe note
|
||||||
|
↓ todo on beforeEach → todo block → describe with note → nested describe with note → it should apply all parent notes to a test with a todo
|
||||||
|
// describe note
|
||||||
|
// nested describe note
|
||||||
|
↓ todo on beforeEach → todo block → describe with note → nested describe with note → it should apply all parent notes as well as the note from the test
|
||||||
|
// describe note
|
||||||
|
// nested describe note
|
||||||
|
// test note
|
||||||
|
↓ todo on beforeEach → todo block → it should not execute
|
||||||
|
↓ todo on test after describe block with beforeEach
|
||||||
|
↓ todo with note on test after describe block with beforeEach
|
||||||
|
// test note
|
||||||
|
|
||||||
PASS Tests\CustomTestCase\ChildTest
|
PASS Tests\CustomTestCase\ChildTest
|
||||||
✓ override method
|
✓ override method
|
||||||
@ -34,6 +80,6 @@
|
|||||||
PASS Tests\CustomTestCase\ParentTest
|
PASS Tests\CustomTestCase\ParentTest
|
||||||
✓ override method
|
✓ override method
|
||||||
|
|
||||||
Tests: 17 todos, 3 passed (3 assertions)
|
Tests: 38 todos, 3 passed (20 assertions)
|
||||||
Duration: x.xxs
|
Duration: x.xxs
|
||||||
|
|
||||||
|
|||||||
@ -15,7 +15,7 @@
|
|||||||
↓ todo on describe → should not fail
|
↓ todo on describe → should not fail
|
||||||
↓ todo on describe → should run
|
↓ todo on describe → should run
|
||||||
|
|
||||||
TODO Tests\Features\Todo - 7 todos
|
TODO Tests\Features\Todo - 28 todos
|
||||||
↓ something todo later
|
↓ something todo later
|
||||||
↓ something todo later chained
|
↓ something todo later chained
|
||||||
↓ something todo later chained and with function body
|
↓ something todo later chained and with function body
|
||||||
@ -24,6 +24,52 @@
|
|||||||
↓ it may have an associated PR #1
|
↓ it may have an associated PR #1
|
||||||
↓ it may have an associated note
|
↓ it may have an associated note
|
||||||
// a note
|
// a note
|
||||||
|
↓ todo on describe → todo block → nested inside todo block → it should not execute
|
||||||
|
↓ todo on describe → todo block → nested inside todo block → it should set the note
|
||||||
|
// hi
|
||||||
|
↓ todo on describe → todo block → describe with note → it should apply the note to a test without a todo
|
||||||
|
// describe note
|
||||||
|
↓ todo on describe → todo block → describe with note → it should apply the note to a test with a todo
|
||||||
|
// describe note
|
||||||
|
↓ todo on describe → todo block → describe with note → it should apply the note as well as the note from the test
|
||||||
|
// describe note
|
||||||
|
// test note
|
||||||
|
↓ todo on describe → todo block → describe with note → nested describe with note → it should apply all parent notes to a test without a todo
|
||||||
|
// describe note
|
||||||
|
// nested describe note
|
||||||
|
↓ todo on describe → todo block → describe with note → nested describe with note → it should apply all parent notes to a test with a todo
|
||||||
|
// describe note
|
||||||
|
// nested describe note
|
||||||
|
↓ todo on describe → todo block → describe with note → nested describe with note → it should apply all parent notes as well as the note from the test
|
||||||
|
// describe note
|
||||||
|
// nested describe note
|
||||||
|
// test note
|
||||||
|
↓ todo on describe → todo block → it should not execute
|
||||||
|
↓ todo on test after describe block
|
||||||
|
↓ todo with note on test after describe block
|
||||||
|
// test note
|
||||||
|
↓ todo on beforeEach → todo block → nested inside todo block → it should not execute
|
||||||
|
↓ todo on beforeEach → todo block → describe with note → it should apply the note to a test without a todo
|
||||||
|
// describe note
|
||||||
|
↓ todo on beforeEach → todo block → describe with note → it should apply the note to a test with a todo
|
||||||
|
// describe note
|
||||||
|
↓ todo on beforeEach → todo block → describe with note → it should apply the note as well as the note from the test
|
||||||
|
// describe note
|
||||||
|
// test note
|
||||||
|
↓ todo on beforeEach → todo block → describe with note → nested describe with note → it should apply all parent notes to a test without a todo
|
||||||
|
// describe note
|
||||||
|
// nested describe note
|
||||||
|
↓ todo on beforeEach → todo block → describe with note → nested describe with note → it should apply all parent notes to a test with a todo
|
||||||
|
// describe note
|
||||||
|
// nested describe note
|
||||||
|
↓ todo on beforeEach → todo block → describe with note → nested describe with note → it should apply all parent notes as well as the note from the test
|
||||||
|
// describe note
|
||||||
|
// nested describe note
|
||||||
|
// test note
|
||||||
|
↓ todo on beforeEach → todo block → it should not execute
|
||||||
|
↓ todo on test after describe block with beforeEach
|
||||||
|
↓ todo with note on test after describe block with beforeEach
|
||||||
|
// test note
|
||||||
|
|
||||||
PASS Tests\CustomTestCase\ChildTest
|
PASS Tests\CustomTestCase\ChildTest
|
||||||
✓ override method
|
✓ override method
|
||||||
@ -34,6 +80,6 @@
|
|||||||
PASS Tests\CustomTestCase\ParentTest
|
PASS Tests\CustomTestCase\ParentTest
|
||||||
✓ override method
|
✓ override method
|
||||||
|
|
||||||
Tests: 17 todos, 3 passed (3 assertions)
|
Tests: 38 todos, 3 passed (20 assertions)
|
||||||
Duration: x.xxs
|
Duration: x.xxs
|
||||||
|
|
||||||
|
|||||||
@ -15,7 +15,7 @@
|
|||||||
↓ todo on describe → should not fail
|
↓ todo on describe → should not fail
|
||||||
↓ todo on describe → should run
|
↓ todo on describe → should run
|
||||||
|
|
||||||
TODO Tests\Features\Todo - 7 todos
|
TODO Tests\Features\Todo - 28 todos
|
||||||
↓ something todo later
|
↓ something todo later
|
||||||
↓ something todo later chained
|
↓ something todo later chained
|
||||||
↓ something todo later chained and with function body
|
↓ something todo later chained and with function body
|
||||||
@ -24,6 +24,52 @@
|
|||||||
↓ it may have an associated PR #1
|
↓ it may have an associated PR #1
|
||||||
↓ it may have an associated note
|
↓ it may have an associated note
|
||||||
// a note
|
// a note
|
||||||
|
↓ todo on describe → todo block → nested inside todo block → it should not execute
|
||||||
|
↓ todo on describe → todo block → nested inside todo block → it should set the note
|
||||||
|
// hi
|
||||||
|
↓ todo on describe → todo block → describe with note → it should apply the note to a test without a todo
|
||||||
|
// describe note
|
||||||
|
↓ todo on describe → todo block → describe with note → it should apply the note to a test with a todo
|
||||||
|
// describe note
|
||||||
|
↓ todo on describe → todo block → describe with note → it should apply the note as well as the note from the test
|
||||||
|
// describe note
|
||||||
|
// test note
|
||||||
|
↓ todo on describe → todo block → describe with note → nested describe with note → it should apply all parent notes to a test without a todo
|
||||||
|
// describe note
|
||||||
|
// nested describe note
|
||||||
|
↓ todo on describe → todo block → describe with note → nested describe with note → it should apply all parent notes to a test with a todo
|
||||||
|
// describe note
|
||||||
|
// nested describe note
|
||||||
|
↓ todo on describe → todo block → describe with note → nested describe with note → it should apply all parent notes as well as the note from the test
|
||||||
|
// describe note
|
||||||
|
// nested describe note
|
||||||
|
// test note
|
||||||
|
↓ todo on describe → todo block → it should not execute
|
||||||
|
↓ todo on test after describe block
|
||||||
|
↓ todo with note on test after describe block
|
||||||
|
// test note
|
||||||
|
↓ todo on beforeEach → todo block → nested inside todo block → it should not execute
|
||||||
|
↓ todo on beforeEach → todo block → describe with note → it should apply the note to a test without a todo
|
||||||
|
// describe note
|
||||||
|
↓ todo on beforeEach → todo block → describe with note → it should apply the note to a test with a todo
|
||||||
|
// describe note
|
||||||
|
↓ todo on beforeEach → todo block → describe with note → it should apply the note as well as the note from the test
|
||||||
|
// describe note
|
||||||
|
// test note
|
||||||
|
↓ todo on beforeEach → todo block → describe with note → nested describe with note → it should apply all parent notes to a test without a todo
|
||||||
|
// describe note
|
||||||
|
// nested describe note
|
||||||
|
↓ todo on beforeEach → todo block → describe with note → nested describe with note → it should apply all parent notes to a test with a todo
|
||||||
|
// describe note
|
||||||
|
// nested describe note
|
||||||
|
↓ todo on beforeEach → todo block → describe with note → nested describe with note → it should apply all parent notes as well as the note from the test
|
||||||
|
// describe note
|
||||||
|
// nested describe note
|
||||||
|
// test note
|
||||||
|
↓ todo on beforeEach → todo block → it should not execute
|
||||||
|
↓ todo on test after describe block with beforeEach
|
||||||
|
↓ todo with note on test after describe block with beforeEach
|
||||||
|
// test note
|
||||||
|
|
||||||
PASS Tests\CustomTestCase\ChildTest
|
PASS Tests\CustomTestCase\ChildTest
|
||||||
✓ override method
|
✓ override method
|
||||||
@ -34,6 +80,6 @@
|
|||||||
PASS Tests\CustomTestCase\ParentTest
|
PASS Tests\CustomTestCase\ParentTest
|
||||||
✓ override method
|
✓ override method
|
||||||
|
|
||||||
Tests: 17 todos, 3 passed (3 assertions)
|
Tests: 38 todos, 3 passed (20 assertions)
|
||||||
Duration: x.xxs
|
Duration: x.xxs
|
||||||
|
|
||||||
|
|||||||
@ -15,7 +15,7 @@
|
|||||||
↓ todo on describe → should not fail
|
↓ todo on describe → should not fail
|
||||||
↓ todo on describe → should run
|
↓ todo on describe → should run
|
||||||
|
|
||||||
TODO Tests\Features\Todo - 7 todos
|
TODO Tests\Features\Todo - 28 todos
|
||||||
↓ something todo later
|
↓ something todo later
|
||||||
↓ something todo later chained
|
↓ something todo later chained
|
||||||
↓ something todo later chained and with function body
|
↓ something todo later chained and with function body
|
||||||
@ -24,6 +24,52 @@
|
|||||||
↓ it may have an associated PR #1
|
↓ it may have an associated PR #1
|
||||||
↓ it may have an associated note
|
↓ it may have an associated note
|
||||||
// a note
|
// a note
|
||||||
|
↓ todo on describe → todo block → nested inside todo block → it should not execute
|
||||||
|
↓ todo on describe → todo block → nested inside todo block → it should set the note
|
||||||
|
// hi
|
||||||
|
↓ todo on describe → todo block → describe with note → it should apply the note to a test without a todo
|
||||||
|
// describe note
|
||||||
|
↓ todo on describe → todo block → describe with note → it should apply the note to a test with a todo
|
||||||
|
// describe note
|
||||||
|
↓ todo on describe → todo block → describe with note → it should apply the note as well as the note from the test
|
||||||
|
// describe note
|
||||||
|
// test note
|
||||||
|
↓ todo on describe → todo block → describe with note → nested describe with note → it should apply all parent notes to a test without a todo
|
||||||
|
// describe note
|
||||||
|
// nested describe note
|
||||||
|
↓ todo on describe → todo block → describe with note → nested describe with note → it should apply all parent notes to a test with a todo
|
||||||
|
// describe note
|
||||||
|
// nested describe note
|
||||||
|
↓ todo on describe → todo block → describe with note → nested describe with note → it should apply all parent notes as well as the note from the test
|
||||||
|
// describe note
|
||||||
|
// nested describe note
|
||||||
|
// test note
|
||||||
|
↓ todo on describe → todo block → it should not execute
|
||||||
|
↓ todo on test after describe block
|
||||||
|
↓ todo with note on test after describe block
|
||||||
|
// test note
|
||||||
|
↓ todo on beforeEach → todo block → nested inside todo block → it should not execute
|
||||||
|
↓ todo on beforeEach → todo block → describe with note → it should apply the note to a test without a todo
|
||||||
|
// describe note
|
||||||
|
↓ todo on beforeEach → todo block → describe with note → it should apply the note to a test with a todo
|
||||||
|
// describe note
|
||||||
|
↓ todo on beforeEach → todo block → describe with note → it should apply the note as well as the note from the test
|
||||||
|
// describe note
|
||||||
|
// test note
|
||||||
|
↓ todo on beforeEach → todo block → describe with note → nested describe with note → it should apply all parent notes to a test without a todo
|
||||||
|
// describe note
|
||||||
|
// nested describe note
|
||||||
|
↓ todo on beforeEach → todo block → describe with note → nested describe with note → it should apply all parent notes to a test with a todo
|
||||||
|
// describe note
|
||||||
|
// nested describe note
|
||||||
|
↓ todo on beforeEach → todo block → describe with note → nested describe with note → it should apply all parent notes as well as the note from the test
|
||||||
|
// describe note
|
||||||
|
// nested describe note
|
||||||
|
// test note
|
||||||
|
↓ todo on beforeEach → todo block → it should not execute
|
||||||
|
↓ todo on test after describe block with beforeEach
|
||||||
|
↓ todo with note on test after describe block with beforeEach
|
||||||
|
// test note
|
||||||
|
|
||||||
PASS Tests\CustomTestCase\ChildTest
|
PASS Tests\CustomTestCase\ChildTest
|
||||||
✓ override method
|
✓ override method
|
||||||
@ -34,6 +80,6 @@
|
|||||||
PASS Tests\CustomTestCase\ParentTest
|
PASS Tests\CustomTestCase\ParentTest
|
||||||
✓ override method
|
✓ override method
|
||||||
|
|
||||||
Tests: 17 todos, 3 passed (3 assertions)
|
Tests: 38 todos, 3 passed (20 assertions)
|
||||||
Duration: x.xxs
|
Duration: x.xxs
|
||||||
|
|
||||||
|
|||||||
@ -1,3 +1,3 @@
|
|||||||
|
|
||||||
Pest Testing Framework 3.0.1.
|
Pest Testing Framework 3.7.0.
|
||||||
|
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
##teamcity[testSuiteStarted name='Tests/tests/Failure' locationHint='file://tests/.tests/Failure.php' flowId='1234']
|
##teamcity[testSuiteStarted name='Tests/tests/Failure' locationHint='pest_qn://tests/.tests/Failure.php' flowId='1234']
|
||||||
##teamcity[testCount count='8' flowId='1234']
|
##teamcity[testCount count='8' flowId='1234']
|
||||||
##teamcity[testStarted name='it can fail with comparison' locationHint='pest_qn://tests/.tests/Failure.php::it can fail with comparison' flowId='1234']
|
##teamcity[testStarted name='it can fail with comparison' locationHint='pest_qn://tests/.tests/Failure.php::it can fail with comparison' flowId='1234']
|
||||||
##teamcity[testFailed name='it can fail with comparison' message='Failed asserting that true matches expected false.' details='at tests/.tests/Failure.php:6' type='comparisonFailure' actual='true' expected='false' flowId='1234']
|
##teamcity[testFailed name='it can fail with comparison' message='Failed asserting that true matches expected false.' details='at tests/.tests/Failure.php:6' type='comparisonFailure' actual='true' expected='false' flowId='1234']
|
||||||
|
|||||||
@ -1,11 +1,15 @@
|
|||||||
##teamcity[testSuiteStarted name='Tests/tests/SuccessOnly' locationHint='file://tests/.tests/SuccessOnly.php' flowId='1234']
|
##teamcity[testSuiteStarted name='Tests/tests/SuccessOnly' locationHint='pest_qn://tests/.tests/SuccessOnly.php' flowId='1234']
|
||||||
##teamcity[testCount count='2' flowId='1234']
|
##teamcity[testCount count='3' 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']
|
||||||
##teamcity[testFinished name='can also pass' duration='100000' flowId='1234']
|
##teamcity[testFinished name='can also pass' duration='100000' flowId='1234']
|
||||||
|
##teamcity[testSuiteStarted name='can pass with dataset' locationHint='pest_qn://tests/.tests/SuccessOnly.php::can pass with dataset' 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[testSuiteFinished name='can pass with dataset' flowId='1234']
|
||||||
##teamcity[testSuiteFinished name='Tests/tests/SuccessOnly' flowId='1234']
|
##teamcity[testSuiteFinished name='Tests/tests/SuccessOnly' flowId='1234']
|
||||||
|
|
||||||
[90mTests:[39m [32;1m2 passed[39;22m[90m (2 assertions)[39m
|
[90mTests:[39m [32;1m3 passed[39;22m[90m (3 assertions)[39m
|
||||||
[90mDuration:[39m [39m1.00s[39m
|
[90mDuration:[39m [39m1.00s[39m
|
||||||
|
|
||||||
|
|||||||
@ -27,6 +27,8 @@
|
|||||||
PASS Tests\Features\AfterEach
|
PASS Tests\Features\AfterEach
|
||||||
✓ 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
|
||||||
|
✓ outer → inner → it does not get executed before the test
|
||||||
|
✓ outer → inner → it should call all parent afterEach functions
|
||||||
|
|
||||||
PASS Tests\Features\Assignee
|
PASS Tests\Features\Assignee
|
||||||
✓ it may be associated with an assignee [@nunomaduro, @taylorotwell]
|
✓ it may be associated with an assignee [@nunomaduro, @taylorotwell]
|
||||||
@ -40,6 +42,9 @@
|
|||||||
PASS Tests\Features\BeforeEach
|
PASS Tests\Features\BeforeEach
|
||||||
✓ it gets executed before each test
|
✓ it gets executed before each test
|
||||||
✓ it gets executed before each test once again
|
✓ it gets executed before each test once again
|
||||||
|
✓ outer → inner → it should call all parent beforeEach functions
|
||||||
|
✓ with expectations → nested block → test
|
||||||
|
✓ with expectations → test
|
||||||
|
|
||||||
PASS Tests\Features\BeforeEachProxiesToTestCallWithExpectations
|
PASS Tests\Features\BeforeEachProxiesToTestCallWithExpectations
|
||||||
✓ runs 1
|
✓ runs 1
|
||||||
@ -178,6 +183,14 @@
|
|||||||
✓ it may be used with high order with dataset "informal"
|
✓ it may be used with high order with dataset "informal"
|
||||||
✓ it may be used with high order even when bound with dataset "formal"
|
✓ it may be used with high order even when bound with dataset "formal"
|
||||||
✓ it may be used with high order even when bound with dataset "informal"
|
✓ it may be used with high order even when bound with dataset "informal"
|
||||||
|
✓ with on nested describe → nested → before inner describe block with (1)
|
||||||
|
✓ with on nested describe → nested → describe → it should include the with value from all parent describe blocks with (1) / (2)
|
||||||
|
✓ with on nested describe → nested → describe → should include the with value from all parent describe blocks and the test with (1) / (2) / (3)
|
||||||
|
✓ with on nested describe → nested → after inner describe block with (1)
|
||||||
|
✓ after describe block with (5)
|
||||||
|
✓ it may be used with high order after describe block with dataset "formal"
|
||||||
|
✓ it may be used with high order after describe block with dataset "informal"
|
||||||
|
✓ after describe block with named dataset with ('after')
|
||||||
|
|
||||||
PASS Tests\Features\Depends
|
PASS Tests\Features\Depends
|
||||||
✓ first
|
✓ first
|
||||||
@ -188,6 +201,13 @@
|
|||||||
✓ depends run test only once
|
✓ depends run test only once
|
||||||
✓ it asserts true is true
|
✓ it asserts true is true
|
||||||
✓ depends works with the correct test name
|
✓ depends works with the correct test name
|
||||||
|
✓ describe block → first in describe
|
||||||
|
✓ describe block → second in describe
|
||||||
|
✓ describe block → third in describe
|
||||||
|
✓ describe block → nested describe → first in nested describe
|
||||||
|
✓ describe block → nested describe → second in nested describe
|
||||||
|
✓ describe block → nested describe → third in nested describe
|
||||||
|
✓ depends on test after describe block
|
||||||
|
|
||||||
PASS Tests\Features\DependsInheritance
|
PASS Tests\Features\DependsInheritance
|
||||||
✓ it is a test
|
✓ it is a test
|
||||||
@ -215,6 +235,7 @@
|
|||||||
✓ depends on describe → bar
|
✓ depends on describe → bar
|
||||||
✓ depends on describe using with → foo with (3)
|
✓ depends on describe using with → foo with (3)
|
||||||
✓ depends on describe using with → bar with (3)
|
✓ depends on describe using with → bar with (3)
|
||||||
|
✓ with test after describe → it should run the before each
|
||||||
|
|
||||||
PASS Tests\Features\DescriptionLess
|
PASS Tests\Features\DescriptionLess
|
||||||
✓ get 'foo'
|
✓ get 'foo'
|
||||||
@ -968,6 +989,16 @@
|
|||||||
✓ it can handle a non-defined exception
|
✓ it can handle a non-defined exception
|
||||||
✓ it can handle a class not found Error
|
✓ it can handle a class not found Error
|
||||||
|
|
||||||
|
PASS Tests\Features\Expect\toUseStrictEquality
|
||||||
|
✓ missing strict equality
|
||||||
|
✓ has strict equality
|
||||||
|
✓ opposite missing strict equality
|
||||||
|
✓ opposite has strict equality
|
||||||
|
|
||||||
|
PASS Tests\Features\Expect\toUseStrictTypes
|
||||||
|
✓ pass
|
||||||
|
✓ failures
|
||||||
|
|
||||||
PASS Tests\Features\Expect\toUseTrait
|
PASS Tests\Features\Expect\toUseTrait
|
||||||
✓ pass
|
✓ pass
|
||||||
✓ failures
|
✓ failures
|
||||||
@ -1057,9 +1088,22 @@
|
|||||||
✓ nested → it may have static note and runtime note
|
✓ nested → it may have static note and runtime note
|
||||||
// This is before each static note
|
// This is before each static note
|
||||||
// This is describe static note
|
// This is describe static note
|
||||||
|
// This is before each describe static note
|
||||||
// This is a static note within describe
|
// This is a static note within describe
|
||||||
// This is before each runtime note
|
// This is before each runtime note
|
||||||
|
// This is before each describe runtime note
|
||||||
// This is a runtime note within describe
|
// This is a runtime note within describe
|
||||||
|
✓ nested → describe nested within describe → it may have a static note and runtime note
|
||||||
|
// This is before each static note
|
||||||
|
// This is describe static note
|
||||||
|
// This is before each describe static note
|
||||||
|
// This is a nested describe static note
|
||||||
|
// This is before each nested describe static note
|
||||||
|
// This is a static note within a nested describe
|
||||||
|
// This is before each runtime note
|
||||||
|
// This is before each describe runtime note
|
||||||
|
// This is before each nested describe runtime note
|
||||||
|
// This is a runtime note within a nested describe
|
||||||
✓ multiple notes
|
✓ multiple notes
|
||||||
// This is before each static note
|
// This is before each static note
|
||||||
// This is before each runtime note
|
// This is before each runtime note
|
||||||
@ -1189,6 +1233,23 @@
|
|||||||
✓ multiple times with repeat iterator with multiple dataset ('c') / ('d') @ repetition 2 of 2
|
✓ multiple times with repeat iterator with multiple dataset ('c') / ('d') @ repetition 2 of 2
|
||||||
✓ multiple times with repeat iterator with multiple dataset ('c') / ('e') @ repetition 2 of 2
|
✓ multiple times with repeat iterator with multiple dataset ('c') / ('e') @ repetition 2 of 2
|
||||||
✓ multiple times with repeat iterator with multiple dataset ('c') / ('f') @ repetition 2 of 2
|
✓ multiple times with repeat iterator with multiple dataset ('c') / ('f') @ repetition 2 of 2
|
||||||
|
✓ describe blocks → multiple times @ repetition 1 of 3
|
||||||
|
✓ describe blocks → multiple times @ repetition 2 of 3
|
||||||
|
✓ describe blocks → multiple times @ repetition 3 of 3
|
||||||
|
✓ describe blocks → describe with repeat → test with no repeat should repeat the number of times specified in the parent describe block @ repetition 1 of 3
|
||||||
|
✓ describe blocks → describe with repeat → test with no repeat should repeat the number of times specified in the parent describe block @ repetition 2 of 3
|
||||||
|
✓ describe blocks → describe with repeat → test with no repeat should repeat the number of times specified in the parent describe block @ repetition 3 of 3
|
||||||
|
✓ describe blocks → describe with repeat → test with repeat should repeat the number of times specified in the test @ repetition 1 of 2
|
||||||
|
✓ describe blocks → describe with repeat → test with repeat should repeat the number of times specified in the test @ repetition 2 of 2
|
||||||
|
✓ describe blocks → describe with repeat → nested describe without repeat → test with no repeat should repeat the number of times specified in the parent's parent describe block @ repetition 1 of 3
|
||||||
|
✓ describe blocks → describe with repeat → nested describe without repeat → test with no repeat should repeat the number of times specified in the parent's parent describe block @ repetition 2 of 3
|
||||||
|
✓ describe blocks → describe with repeat → nested describe without repeat → test with no repeat should repeat the number of times specified in the parent's parent describe block @ repetition 3 of 3
|
||||||
|
✓ describe blocks → describe with repeat → nested describe without repeat → test with repeat should repeat the number of times specified in the test @ repetition 1 of 2
|
||||||
|
✓ describe blocks → describe with repeat → nested describe without repeat → test with repeat should repeat the number of times specified in the test @ repetition 2 of 2
|
||||||
|
✓ describe blocks → describe with repeat → nested describe with repeat → test with no repeat should repeat the number of times specified in the parent describe block @ repetition 1 of 2
|
||||||
|
✓ describe blocks → describe with repeat → nested describe with repeat → test with no repeat should repeat the number of times specified in the parent describe block @ repetition 2 of 2
|
||||||
|
✓ describe blocks → describe with repeat → nested describe with repeat → test with repeat should repeat the number of times specified in the test @ repetition 1 of 2
|
||||||
|
✓ describe blocks → describe with repeat → nested describe with repeat → test with repeat should repeat the number of times specified in the test @ repetition 2 of 2
|
||||||
|
|
||||||
PASS Tests\Features\ScopedDatasets\Directory\NestedDirectory1\TestFileInNestedDirectoryWithDatasetsFile
|
PASS Tests\Features\ScopedDatasets\Directory\NestedDirectory1\TestFileInNestedDirectoryWithDatasetsFile
|
||||||
✓ uses dataset with (1)
|
✓ uses dataset with (1)
|
||||||
@ -1245,6 +1306,14 @@
|
|||||||
- it skips when skip after assertion
|
- it skips when skip after assertion
|
||||||
- it can use something in the test case as a condition → This test was skipped
|
- it can use something in the test case as a condition → This test was skipped
|
||||||
- it can user higher order callables and skip
|
- it can user higher order callables and skip
|
||||||
|
- skip on describe → skipped tests → nested inside skipped block → it should not execute
|
||||||
|
- skip on describe → skipped tests → it should not execute
|
||||||
|
✓ skip on describe → it should execute
|
||||||
|
- skip on beforeEach → skipped tests → nested inside skipped block → it should not execute
|
||||||
|
- skip on beforeEach → skipped tests → it should not execute
|
||||||
|
✓ skip on beforeEach → it should execute
|
||||||
|
✓ it does not skip after the describe block
|
||||||
|
- it can skip after the describe block
|
||||||
|
|
||||||
WARN Tests\Features\SkipOnPhp
|
WARN Tests\Features\SkipOnPhp
|
||||||
✓ it can run on php version
|
✓ it can run on php version
|
||||||
@ -1265,7 +1334,7 @@
|
|||||||
✓ nested → it may be associated with an ticket #1, #4, #5, #6, #3
|
✓ nested → it may be associated with an ticket #1, #4, #5, #6, #3
|
||||||
// an note between an the ticket
|
// an note between an the ticket
|
||||||
|
|
||||||
PASS Tests\Features\Todo - 7 todos
|
PASS Tests\Features\Todo - 28 todos
|
||||||
↓ something todo later
|
↓ something todo later
|
||||||
↓ something todo later chained
|
↓ something todo later chained
|
||||||
↓ something todo later chained and with function body
|
↓ something todo later chained and with function body
|
||||||
@ -1275,6 +1344,54 @@
|
|||||||
↓ it may have an associated PR #1
|
↓ it may have an associated PR #1
|
||||||
↓ it may have an associated note
|
↓ it may have an associated note
|
||||||
// a note
|
// a note
|
||||||
|
↓ todo on describe → todo block → nested inside todo block → it should not execute
|
||||||
|
↓ todo on describe → todo block → nested inside todo block → it should set the note
|
||||||
|
// hi
|
||||||
|
↓ todo on describe → todo block → describe with note → it should apply the note to a test without a todo
|
||||||
|
// describe note
|
||||||
|
↓ todo on describe → todo block → describe with note → it should apply the note to a test with a todo
|
||||||
|
// describe note
|
||||||
|
↓ todo on describe → todo block → describe with note → it should apply the note as well as the note from the test
|
||||||
|
// describe note
|
||||||
|
// test note
|
||||||
|
↓ todo on describe → todo block → describe with note → nested describe with note → it should apply all parent notes to a test without a todo
|
||||||
|
// describe note
|
||||||
|
// nested describe note
|
||||||
|
↓ todo on describe → todo block → describe with note → nested describe with note → it should apply all parent notes to a test with a todo
|
||||||
|
// describe note
|
||||||
|
// nested describe note
|
||||||
|
↓ todo on describe → todo block → describe with note → nested describe with note → it should apply all parent notes as well as the note from the test
|
||||||
|
// describe note
|
||||||
|
// nested describe note
|
||||||
|
// test note
|
||||||
|
↓ todo on describe → todo block → it should not execute
|
||||||
|
✓ todo on describe → it should execute
|
||||||
|
↓ todo on test after describe block
|
||||||
|
↓ todo with note on test after describe block
|
||||||
|
// test note
|
||||||
|
↓ todo on beforeEach → todo block → nested inside todo block → it should not execute
|
||||||
|
↓ todo on beforeEach → todo block → describe with note → it should apply the note to a test without a todo
|
||||||
|
// describe note
|
||||||
|
↓ todo on beforeEach → todo block → describe with note → it should apply the note to a test with a todo
|
||||||
|
// describe note
|
||||||
|
↓ todo on beforeEach → todo block → describe with note → it should apply the note as well as the note from the test
|
||||||
|
// describe note
|
||||||
|
// test note
|
||||||
|
↓ todo on beforeEach → todo block → describe with note → nested describe with note → it should apply all parent notes to a test without a todo
|
||||||
|
// describe note
|
||||||
|
// nested describe note
|
||||||
|
↓ todo on beforeEach → todo block → describe with note → nested describe with note → it should apply all parent notes to a test with a todo
|
||||||
|
// describe note
|
||||||
|
// nested describe note
|
||||||
|
↓ todo on beforeEach → todo block → describe with note → nested describe with note → it should apply all parent notes as well as the note from the test
|
||||||
|
// describe note
|
||||||
|
// nested describe note
|
||||||
|
// test note
|
||||||
|
↓ todo on beforeEach → todo block → it should not execute
|
||||||
|
✓ todo on beforeEach → it should execute
|
||||||
|
↓ todo on test after describe block with beforeEach
|
||||||
|
↓ todo with note on test after describe block with beforeEach
|
||||||
|
// test note
|
||||||
|
|
||||||
WARN Tests\Features\Warnings
|
WARN Tests\Features\Warnings
|
||||||
! warning → Undefined property: P\Tests\Features\Warnings::$fooqwdfwqdfqw
|
! warning → Undefined property: P\Tests\Features\Warnings::$fooqwdfwqdfqw
|
||||||
@ -1305,6 +1422,7 @@
|
|||||||
✓ it executes tests in the Helpers directory
|
✓ it executes tests in the Helpers directory
|
||||||
|
|
||||||
PASS Tests\Hooks\AfterEachTest
|
PASS Tests\Hooks\AfterEachTest
|
||||||
|
✓ nested → nested afterEach execution order
|
||||||
✓ global afterEach execution order
|
✓ global afterEach execution order
|
||||||
|
|
||||||
PASS Tests\Hooks\BeforeEachTest
|
PASS Tests\Hooks\BeforeEachTest
|
||||||
@ -1373,6 +1491,16 @@
|
|||||||
PASS Tests\Playground
|
PASS Tests\Playground
|
||||||
✓ basic
|
✓ basic
|
||||||
|
|
||||||
|
PASS Tests\Plugins\Coverage
|
||||||
|
✓ compute comparable coverage with (0, 0)
|
||||||
|
✓ compute comparable coverage with (0.5, 0.5)
|
||||||
|
✓ compute comparable coverage with (1.0, 1.0)
|
||||||
|
✓ compute comparable coverage with (32.51, 32.5)
|
||||||
|
✓ compute comparable coverage with (32.12312321312312, 32.1)
|
||||||
|
✓ compute comparable coverage with (32.53333333333333, 32.5)
|
||||||
|
✓ compute comparable coverage with (32.57777771232132, 32.5)
|
||||||
|
✓ compute comparable coverage with (100.0, 100.0)
|
||||||
|
|
||||||
PASS Tests\Plugins\Traits
|
PASS Tests\Plugins\Traits
|
||||||
✓ it allows global uses
|
✓ it allows global uses
|
||||||
✓ it allows multiple global uses registered in the same path
|
✓ it allows multiple global uses registered in the same path
|
||||||
@ -1381,7 +1509,7 @@
|
|||||||
✓ it proxies to uses call
|
✓ it proxies to uses call
|
||||||
|
|
||||||
PASS Tests\Unit\Configuration\Theme
|
PASS Tests\Unit\Configuration\Theme
|
||||||
✓ it creates a theme instance
|
✓ it creates a printer instance
|
||||||
|
|
||||||
PASS Tests\Unit\Console\Help
|
PASS Tests\Unit\Console\Help
|
||||||
✓ it outputs the help information when --help is used
|
✓ it outputs the help information when --help is used
|
||||||
@ -1422,6 +1550,13 @@
|
|||||||
✓ preset invalid name
|
✓ preset invalid name
|
||||||
✓ preset → myFramework
|
✓ preset → myFramework
|
||||||
|
|
||||||
|
PASS Tests\Unit\Support\Arr
|
||||||
|
✓ last → it should return false for an empty arary
|
||||||
|
✓ last → it should return the last element for an array with a single element
|
||||||
|
✓ last → it should return the last element for an array without changing the internal pointer
|
||||||
|
✓ last → it should return the last element for an associative array without changing the internal pointer
|
||||||
|
✓ last → it should return the last element for an mixed key array without changing the internal pointer
|
||||||
|
|
||||||
PASS Tests\Unit\Support\Backtrace
|
PASS Tests\Unit\Support\Backtrace
|
||||||
✓ it gets file name from called file
|
✓ it gets file name from called file
|
||||||
|
|
||||||
@ -1573,4 +1708,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, 17 todos, 28 skipped, 1088 passed (2615 assertions)
|
Tests: 2 deprecated, 4 warnings, 5 incomplete, 2 notices, 38 todos, 33 skipped, 1152 passed (2744 assertions)
|
||||||
@ -9,3 +9,7 @@ it('can pass with comparison', function () {
|
|||||||
test('can also pass', function () {
|
test('can also pass', function () {
|
||||||
expect("string")->toBeString();
|
expect("string")->toBeString();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
test('can pass with dataset', function ($value) {
|
||||||
|
expect($value)->toEqual(true);
|
||||||
|
})->with([true]);
|
||||||
|
|||||||
@ -26,3 +26,25 @@ it('gets executed after the test', function () {
|
|||||||
afterEach(function () {
|
afterEach(function () {
|
||||||
$this->state->bar = 2;
|
$this->state->bar = 2;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe('outer', function () {
|
||||||
|
afterEach(function () {
|
||||||
|
$this->state->bar++;
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('inner', function () {
|
||||||
|
afterEach(function () {
|
||||||
|
$this->state->bar++;
|
||||||
|
});
|
||||||
|
|
||||||
|
it('does not get executed before the test', function () {
|
||||||
|
expect($this->state)->toHaveProperty('bar');
|
||||||
|
expect($this->state->bar)->toBe(2);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should call all parent afterEach functions', function () {
|
||||||
|
expect($this->state)->toHaveProperty('bar');
|
||||||
|
expect($this->state->bar)->toBe(4);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|||||||
@ -25,3 +25,29 @@ it('gets executed before each test once again', function () {
|
|||||||
beforeEach(function () {
|
beforeEach(function () {
|
||||||
$this->bar++;
|
$this->bar++;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe('outer', function () {
|
||||||
|
beforeEach(function () {
|
||||||
|
$this->bar++;
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('inner', function () {
|
||||||
|
beforeEach(function () {
|
||||||
|
$this->bar++;
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should call all parent beforeEach functions', function () {
|
||||||
|
expect($this->bar)->toBe(3);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('with expectations', function () {
|
||||||
|
beforeEach()->expect(true)->toBeTrue();
|
||||||
|
|
||||||
|
describe('nested block', function () {
|
||||||
|
test('test', function () {});
|
||||||
|
});
|
||||||
|
|
||||||
|
test('test', function () {});
|
||||||
|
});
|
||||||
|
|||||||
@ -392,3 +392,40 @@ it('may be used with high order even when bound')
|
|||||||
->with('greeting-bound')
|
->with('greeting-bound')
|
||||||
->expect(fn (string $greeting) => $greeting)
|
->expect(fn (string $greeting) => $greeting)
|
||||||
->throws(InvalidArgumentException::class);
|
->throws(InvalidArgumentException::class);
|
||||||
|
|
||||||
|
describe('with on nested describe', function () {
|
||||||
|
describe('nested', function () {
|
||||||
|
test('before inner describe block', function (...$args) {
|
||||||
|
expect($args)->toBe([1]);
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('describe', function () {
|
||||||
|
it('should include the with value from all parent describe blocks', function (...$args) {
|
||||||
|
expect($args)->toBe([1, 2]);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('should include the with value from all parent describe blocks and the test', function (...$args) {
|
||||||
|
expect($args)->toBe([1, 2, 3]);
|
||||||
|
})->with([3]);
|
||||||
|
})->with([2]);
|
||||||
|
|
||||||
|
test('after inner describe block', function (...$args) {
|
||||||
|
expect($args)->toBe([1]);
|
||||||
|
});
|
||||||
|
})->with([1]);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('after describe block', function (...$args) {
|
||||||
|
expect($args)->toBe([5]);
|
||||||
|
})->with([5]);
|
||||||
|
|
||||||
|
it('may be used with high order after describe block')
|
||||||
|
->with('greeting-string')
|
||||||
|
->expect(fn (string $greeting) => $greeting)
|
||||||
|
->throwsNoExceptions();
|
||||||
|
|
||||||
|
dataset('after-describe', ['after']);
|
||||||
|
|
||||||
|
test('after describe block with named dataset', function (...$args) {
|
||||||
|
expect($args)->toBe(['after']);
|
||||||
|
})->with('after-describe');
|
||||||
|
|||||||
@ -36,3 +36,43 @@ test('depends run test only once', function () use (&$runCounter) {
|
|||||||
// Regression tests. See https://github.com/pestphp/pest/pull/216
|
// Regression tests. See https://github.com/pestphp/pest/pull/216
|
||||||
it('asserts true is true')->assertTrue(true);
|
it('asserts true is true')->assertTrue(true);
|
||||||
test('depends works with the correct test name')->assertTrue(true)->depends('it asserts true is true');
|
test('depends works with the correct test name')->assertTrue(true)->depends('it asserts true is true');
|
||||||
|
|
||||||
|
describe('describe block', function () {
|
||||||
|
$runCounter = 0;
|
||||||
|
|
||||||
|
test('first in describe', function () use (&$runCounter) {
|
||||||
|
$runCounter++;
|
||||||
|
expect(true)->toBeTrue();
|
||||||
|
});
|
||||||
|
|
||||||
|
test('second in describe', function () use (&$runCounter) {
|
||||||
|
expect($runCounter)->toBe(1);
|
||||||
|
$runCounter++;
|
||||||
|
})->depends('first in describe');
|
||||||
|
|
||||||
|
test('third in describe', function () use (&$runCounter) {
|
||||||
|
expect($runCounter)->toBe(2);
|
||||||
|
})->depends('second in describe');
|
||||||
|
|
||||||
|
describe('nested describe', function () {
|
||||||
|
$runCounter = 0;
|
||||||
|
|
||||||
|
test('first in nested describe', function () use (&$runCounter) {
|
||||||
|
$runCounter++;
|
||||||
|
expect(true)->toBeTrue();
|
||||||
|
});
|
||||||
|
|
||||||
|
test('second in nested describe', function () use (&$runCounter) {
|
||||||
|
expect($runCounter)->toBe(1);
|
||||||
|
$runCounter++;
|
||||||
|
})->depends('first in nested describe');
|
||||||
|
|
||||||
|
test('third in nested describe', function () use (&$runCounter) {
|
||||||
|
expect($runCounter)->toBe(2);
|
||||||
|
})->depends('second in nested describe');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
test('depends on test after describe block', function () use (&$runCounter) {
|
||||||
|
expect($runCounter)->toBe(2);
|
||||||
|
})->depends('first', 'second');
|
||||||
|
|||||||
@ -96,3 +96,15 @@ describe('depends on describe using with', function () {
|
|||||||
expect($foo + $foo)->toBe(6);
|
expect($foo + $foo)->toBe(6);
|
||||||
})->depends('foo');
|
})->depends('foo');
|
||||||
})->with([3]);
|
})->with([3]);
|
||||||
|
|
||||||
|
describe('with test after describe', function () {
|
||||||
|
beforeEach(function () {
|
||||||
|
$this->count++;
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('foo', function () {});
|
||||||
|
|
||||||
|
it('should run the before each', function () {
|
||||||
|
expect($this->count)->toBe(2);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|||||||
21
tests/Features/Expect/toUseStrictEquality.php
Normal file
21
tests/Features/Expect/toUseStrictEquality.php
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
use Pest\Arch\Exceptions\ArchExpectationFailedException;
|
||||||
|
|
||||||
|
test('missing strict equality')
|
||||||
|
->throws(ArchExpectationFailedException::class)
|
||||||
|
->expect('Tests\\Fixtures\\Arch\\ToUseStrictEquality\\NotStrictEquality')
|
||||||
|
->toUseStrictEquality();
|
||||||
|
|
||||||
|
test('has strict equality')
|
||||||
|
->expect('Tests\\Fixtures\\Arch\\ToUseStrictEquality\\StrictEquality')
|
||||||
|
->toUseStrictEquality();
|
||||||
|
|
||||||
|
test('opposite missing strict equality')
|
||||||
|
->throws(ArchExpectationFailedException::class)
|
||||||
|
->expect('Tests\\Fixtures\\Arch\\ToUseStrictEquality\\StrictEquality')
|
||||||
|
->not->toUseStrictEquality();
|
||||||
|
|
||||||
|
test('opposite has strict equality')
|
||||||
|
->expect('Tests\\Fixtures\\Arch\\ToUseStrictEquality\\NotStrictEquality')
|
||||||
|
->not->toUseStrictEquality();
|
||||||
17
tests/Features/Expect/toUseStrictTypes.php
Normal file
17
tests/Features/Expect/toUseStrictTypes.php
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
use Pest\Arch\Exceptions\ArchExpectationFailedException;
|
||||||
|
use Tests\Fixtures\Arch\ToUseStrictTypes\HasNoStrictType;
|
||||||
|
use Tests\Fixtures\Arch\ToUseStrictTypes\HasStrictType;
|
||||||
|
use Tests\Fixtures\Arch\ToUseStrictTypes\HasStrictTypeWithCommentsAbove;
|
||||||
|
|
||||||
|
test('pass', function () {
|
||||||
|
expect(HasStrictType::class)->toUseStrictTypes()
|
||||||
|
->and(HasStrictTypeWithCommentsAbove::class)->toUseStrictTypes();
|
||||||
|
});
|
||||||
|
|
||||||
|
test('failures', function () {
|
||||||
|
expect(HasNoStrictType::class)->toUseStrictTypes();
|
||||||
|
})->throws(ArchExpectationFailedException::class);
|
||||||
@ -21,11 +21,27 @@ it('may have static note and runtime note', function () {
|
|||||||
})->note('This is a static note');
|
})->note('This is a static note');
|
||||||
|
|
||||||
describe('nested', function () {
|
describe('nested', function () {
|
||||||
|
beforeEach(function () {
|
||||||
|
$this->note('This is before each describe runtime note');
|
||||||
|
})->note('This is before each describe static note');
|
||||||
|
|
||||||
it('may have static note and runtime note', function () {
|
it('may have static note and runtime note', function () {
|
||||||
expect(true)->toBeTrue(true);
|
expect(true)->toBeTrue(true);
|
||||||
|
|
||||||
$this->note('This is a runtime note within describe');
|
$this->note('This is a runtime note within describe');
|
||||||
})->note('This is a static note within describe');
|
})->note('This is a static note within describe');
|
||||||
|
|
||||||
|
describe('describe nested within describe', function () {
|
||||||
|
beforeEach(function () {
|
||||||
|
$this->note('This is before each nested describe runtime note');
|
||||||
|
})->note('This is before each nested describe static note');
|
||||||
|
|
||||||
|
it('may have a static note and runtime note', function () {
|
||||||
|
expect(true)->toBeTrue(true);
|
||||||
|
|
||||||
|
$this->note('This is a runtime note within a nested describe');
|
||||||
|
})->note('This is a static note within a nested describe');
|
||||||
|
})->note('This is a nested describe static note');
|
||||||
})->note('This is describe static note');
|
})->note('This is describe static note');
|
||||||
|
|
||||||
test('multiple notes', function () {
|
test('multiple notes', function () {
|
||||||
|
|||||||
@ -43,3 +43,39 @@ test('multiple times with repeat iterator with multiple dataset', function (stri
|
|||||||
->toBeNumeric()
|
->toBeNumeric()
|
||||||
->toBeGreaterThan(0);
|
->toBeGreaterThan(0);
|
||||||
})->repeat(times: 2)->with(['a', 'b', 'c'], ['d', 'e', 'f']);
|
})->repeat(times: 2)->with(['a', 'b', 'c'], ['d', 'e', 'f']);
|
||||||
|
|
||||||
|
describe('describe blocks', function () {
|
||||||
|
test('multiple times', function () {
|
||||||
|
expect(true)->toBeTrue();
|
||||||
|
})->repeat(times: 3);
|
||||||
|
|
||||||
|
describe('describe with repeat', function () {
|
||||||
|
test('test with no repeat should repeat the number of times specified in the parent describe block', function () {
|
||||||
|
expect(true)->toBeTrue();
|
||||||
|
});
|
||||||
|
|
||||||
|
test('test with repeat should repeat the number of times specified in the test', function () {
|
||||||
|
expect(true)->toBeTrue();
|
||||||
|
})->repeat(times: 2);
|
||||||
|
|
||||||
|
describe('nested describe without repeat', function () {
|
||||||
|
test("test with no repeat should repeat the number of times specified in the parent's parent describe block", function () {
|
||||||
|
expect(true)->toBeTrue();
|
||||||
|
});
|
||||||
|
|
||||||
|
test('test with repeat should repeat the number of times specified in the test', function () {
|
||||||
|
expect(true)->toBeTrue();
|
||||||
|
})->repeat(times: 2);
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('nested describe with repeat', function () {
|
||||||
|
test('test with no repeat should repeat the number of times specified in the parent describe block', function () {
|
||||||
|
expect(true)->toBeTrue();
|
||||||
|
});
|
||||||
|
|
||||||
|
test('test with repeat should repeat the number of times specified in the test', function () {
|
||||||
|
expect(true)->toBeTrue();
|
||||||
|
})->repeat(times: 2);
|
||||||
|
})->repeat(times: 2);
|
||||||
|
})->repeat(times: 3);
|
||||||
|
});
|
||||||
|
|||||||
@ -54,3 +54,81 @@ it('can user higher order callables and skip')
|
|||||||
return $this->shouldSkip;
|
return $this->shouldSkip;
|
||||||
})
|
})
|
||||||
->toBeFalse();
|
->toBeFalse();
|
||||||
|
|
||||||
|
describe('skip on describe', function () {
|
||||||
|
beforeEach(function () {
|
||||||
|
$this->ran = false;
|
||||||
|
});
|
||||||
|
|
||||||
|
afterEach(function () {
|
||||||
|
match ($this->name()) {
|
||||||
|
'__pest_evaluable__skip_on_describe__→__skipped_tests__→__nested_inside_skipped_block__→_it_should_not_execute' => expect($this->ran)->toBe(false),
|
||||||
|
'__pest_evaluable__skip_on_describe__→__skipped_tests__→_it_should_not_execute' => expect($this->ran)->toBe(false),
|
||||||
|
'__pest_evaluable__skip_on_describe__→_it_should_execute' => expect($this->ran)->toBe(true),
|
||||||
|
default => $this->fail('Unexpected test name: '.$this->name()),
|
||||||
|
};
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('skipped tests', function () {
|
||||||
|
describe('nested inside skipped block', function () {
|
||||||
|
it('should not execute', function () {
|
||||||
|
$this->ran = true;
|
||||||
|
$this->fail();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should not execute', function () {
|
||||||
|
$this->ran = true;
|
||||||
|
$this->fail();
|
||||||
|
});
|
||||||
|
})->skip();
|
||||||
|
|
||||||
|
it('should execute', function () {
|
||||||
|
$this->ran = true;
|
||||||
|
expect($this->ran)->toBe(true);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('skip on beforeEach', function () {
|
||||||
|
beforeEach(function () {
|
||||||
|
$this->ran = false;
|
||||||
|
});
|
||||||
|
|
||||||
|
afterEach(function () {
|
||||||
|
match ($this->name()) {
|
||||||
|
'__pest_evaluable__skip_on_beforeEach__→__skipped_tests__→__nested_inside_skipped_block__→_it_should_not_execute' => expect($this->ran)->toBe(false),
|
||||||
|
'__pest_evaluable__skip_on_beforeEach__→__skipped_tests__→_it_should_not_execute' => expect($this->ran)->toBe(false),
|
||||||
|
'__pest_evaluable__skip_on_beforeEach__→_it_should_execute' => expect($this->ran)->toBe(true),
|
||||||
|
default => $this->fail('Unexpected test name: '.$this->name()),
|
||||||
|
};
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('skipped tests', function () {
|
||||||
|
beforeEach()->skip();
|
||||||
|
|
||||||
|
describe('nested inside skipped block', function () {
|
||||||
|
it('should not execute', function () {
|
||||||
|
$this->ran = true;
|
||||||
|
$this->fail();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should not execute', function () {
|
||||||
|
$this->ran = true;
|
||||||
|
$this->fail();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should execute', function () {
|
||||||
|
$this->ran = true;
|
||||||
|
expect($this->ran)->toBe(true);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('does not skip after the describe block', function () {
|
||||||
|
expect(true)->toBeTrue();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('can skip after the describe block', function () {
|
||||||
|
expect(true)->toBeTrue();
|
||||||
|
})->skip();
|
||||||
|
|||||||
@ -27,3 +27,175 @@ it('may have an associated PR', function () {
|
|||||||
it('may have an associated note', function () {
|
it('may have an associated note', function () {
|
||||||
expect(true)->toBeTrue();
|
expect(true)->toBeTrue();
|
||||||
})->todo(note: 'a note');
|
})->todo(note: 'a note');
|
||||||
|
|
||||||
|
describe('todo on describe', function () {
|
||||||
|
beforeEach(function () {
|
||||||
|
$this->ran = false;
|
||||||
|
});
|
||||||
|
|
||||||
|
afterEach(function () {
|
||||||
|
match ($this->name()) {
|
||||||
|
'__pest_evaluable__todo_on_describe__→__todo_block__→__nested_inside_todo_block__→_it_should_not_execute' => expect($this->ran)->toBe(false),
|
||||||
|
'__pest_evaluable__todo_on_describe__→__todo_block__→__nested_inside_todo_block__→_it_should_set_the_note' => expect($this->ran)->toBe(false),
|
||||||
|
'__pest_evaluable__todo_on_describe__→__todo_block__→__describe_with_note__→_it_should_apply_the_note_to_a_test_without_a_todo' => expect($this->ran)->toBe(false),
|
||||||
|
'__pest_evaluable__todo_on_describe__→__todo_block__→__describe_with_note__→_it_should_apply_the_note_to_a_test_with_a_todo' => expect($this->ran)->toBe(false),
|
||||||
|
'__pest_evaluable__todo_on_describe__→__todo_block__→__describe_with_note__→_it_should_apply_the_note_as_well_as_the_note_from_the_test' => expect($this->ran)->toBe(false),
|
||||||
|
'__pest_evaluable__todo_on_describe__→__todo_block__→__describe_with_note__→__nested_describe_with_note__→_it_should_apply_all_parent_notes_to_a_test_without_a_todo' => expect($this->ran)->toBe(false),
|
||||||
|
'__pest_evaluable__todo_on_describe__→__todo_block__→__describe_with_note__→__nested_describe_with_note__→_it_should_apply_all_parent_notes_to_a_test_with_a_todo' => expect($this->ran)->toBe(false),
|
||||||
|
'__pest_evaluable__todo_on_describe__→__todo_block__→__describe_with_note__→__nested_describe_with_note__→_it_should_apply_all_parent_notes_as_well_as_the_note_from_the_test' => expect($this->ran)->toBe(false),
|
||||||
|
'__pest_evaluable__todo_on_describe__→__todo_block__→_it_should_not_execute' => expect($this->ran)->toBe(false),
|
||||||
|
'__pest_evaluable__todo_on_describe__→_it_should_execute' => expect($this->ran)->toBe(true),
|
||||||
|
default => $this->fail('Unexpected test name: '.$this->name()),
|
||||||
|
};
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('todo block', function () {
|
||||||
|
describe('nested inside todo block', function () {
|
||||||
|
it('should not execute', function () {
|
||||||
|
$this->ran = true;
|
||||||
|
$this->fail();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should set the note', function () {
|
||||||
|
$this->ran = true;
|
||||||
|
$this->fail();
|
||||||
|
})->todo(note: 'hi');
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('describe with note', function () {
|
||||||
|
it('should apply the note to a test without a todo', function () {
|
||||||
|
$this->ran = true;
|
||||||
|
$this->fail();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should apply the note to a test with a todo', function () {
|
||||||
|
$this->ran = true;
|
||||||
|
$this->fail();
|
||||||
|
})->todo();
|
||||||
|
|
||||||
|
it('should apply the note as well as the note from the test', function () {
|
||||||
|
$this->ran = true;
|
||||||
|
$this->fail();
|
||||||
|
})->todo(note: 'test note');
|
||||||
|
|
||||||
|
describe('nested describe with note', function () {
|
||||||
|
it('should apply all parent notes to a test without a todo', function () {
|
||||||
|
$this->ran = true;
|
||||||
|
$this->fail();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should apply all parent notes to a test with a todo', function () {
|
||||||
|
$this->ran = true;
|
||||||
|
$this->fail();
|
||||||
|
})->todo();
|
||||||
|
|
||||||
|
it('should apply all parent notes as well as the note from the test', function () {
|
||||||
|
$this->ran = true;
|
||||||
|
$this->fail();
|
||||||
|
})->todo(note: 'test note');
|
||||||
|
})->todo(note: 'nested describe note');
|
||||||
|
})->todo(note: 'describe note');
|
||||||
|
|
||||||
|
it('should not execute', function () {
|
||||||
|
$this->ran = true;
|
||||||
|
$this->fail();
|
||||||
|
});
|
||||||
|
})->todo();
|
||||||
|
|
||||||
|
it('should execute', function () {
|
||||||
|
$this->ran = true;
|
||||||
|
expect($this->ran)->toBe(true);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
test('todo on test after describe block', function () {
|
||||||
|
$this->fail();
|
||||||
|
})->todo();
|
||||||
|
|
||||||
|
test('todo with note on test after describe block', function () {
|
||||||
|
$this->fail();
|
||||||
|
})->todo(note: 'test note');
|
||||||
|
|
||||||
|
describe('todo on beforeEach', function () {
|
||||||
|
beforeEach(function () {
|
||||||
|
$this->ran = false;
|
||||||
|
});
|
||||||
|
|
||||||
|
afterEach(function () {
|
||||||
|
match ($this->name()) {
|
||||||
|
'__pest_evaluable__todo_on_beforeEach__→__todo_block__→__nested_inside_todo_block__→_it_should_not_execute' => expect($this->ran)->toBe(false),
|
||||||
|
'__pest_evaluable__todo_on_beforeEach__→__todo_block__→_it_should_not_execute' => expect($this->ran)->toBe(false),
|
||||||
|
'__pest_evaluable__todo_on_beforeEach__→__todo_block__→__describe_with_note__→_it_should_apply_the_note_to_a_test_without_a_todo' => expect($this->ran)->toBe(false),
|
||||||
|
'__pest_evaluable__todo_on_beforeEach__→__todo_block__→__describe_with_note__→_it_should_apply_the_note_to_a_test_with_a_todo' => expect($this->ran)->toBe(false),
|
||||||
|
'__pest_evaluable__todo_on_beforeEach__→__todo_block__→__describe_with_note__→_it_should_apply_the_note_as_well_as_the_note_from_the_test' => expect($this->ran)->toBe(false),
|
||||||
|
'__pest_evaluable__todo_on_beforeEach__→__todo_block__→__describe_with_note__→__nested_describe_with_note__→_it_should_apply_all_parent_notes_to_a_test_without_a_todo' => expect($this->ran)->toBe(false),
|
||||||
|
'__pest_evaluable__todo_on_beforeEach__→__todo_block__→__describe_with_note__→__nested_describe_with_note__→_it_should_apply_all_parent_notes_to_a_test_with_a_todo' => expect($this->ran)->toBe(false),
|
||||||
|
'__pest_evaluable__todo_on_beforeEach__→__todo_block__→__describe_with_note__→__nested_describe_with_note__→_it_should_apply_all_parent_notes_as_well_as_the_note_from_the_test' => expect($this->ran)->toBe(false),
|
||||||
|
'__pest_evaluable__todo_on_beforeEach__→_it_should_execute' => expect($this->ran)->toBe(true),
|
||||||
|
default => $this->fail('Unexpected test name: '.$this->name()),
|
||||||
|
};
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('todo block', function () {
|
||||||
|
beforeEach()->todo();
|
||||||
|
|
||||||
|
describe('nested inside todo block', function () {
|
||||||
|
it('should not execute', function () {
|
||||||
|
$this->ran = true;
|
||||||
|
$this->fail();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('describe with note', function () {
|
||||||
|
it('should apply the note to a test without a todo', function () {
|
||||||
|
$this->ran = true;
|
||||||
|
$this->fail();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should apply the note to a test with a todo', function () {
|
||||||
|
$this->ran = true;
|
||||||
|
$this->fail();
|
||||||
|
})->todo();
|
||||||
|
|
||||||
|
it('should apply the note as well as the note from the test', function () {
|
||||||
|
$this->ran = true;
|
||||||
|
$this->fail();
|
||||||
|
})->todo(note: 'test note');
|
||||||
|
|
||||||
|
describe('nested describe with note', function () {
|
||||||
|
it('should apply all parent notes to a test without a todo', function () {
|
||||||
|
$this->ran = true;
|
||||||
|
$this->fail();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should apply all parent notes to a test with a todo', function () {
|
||||||
|
$this->ran = true;
|
||||||
|
$this->fail();
|
||||||
|
})->todo();
|
||||||
|
|
||||||
|
it('should apply all parent notes as well as the note from the test', function () {
|
||||||
|
$this->ran = true;
|
||||||
|
$this->fail();
|
||||||
|
})->todo(note: 'test note');
|
||||||
|
})->todo(note: 'nested describe note');
|
||||||
|
})->todo(note: 'describe note');
|
||||||
|
|
||||||
|
it('should not execute', function () {
|
||||||
|
$this->ran = true;
|
||||||
|
$this->fail();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should execute', function () {
|
||||||
|
$this->ran = true;
|
||||||
|
expect($this->ran)->toBe(true);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
test('todo on test after describe block with beforeEach', function () {
|
||||||
|
$this->fail();
|
||||||
|
})->todo();
|
||||||
|
|
||||||
|
test('todo with note on test after describe block with beforeEach', function () {
|
||||||
|
$this->fail();
|
||||||
|
})->todo(note: 'test note');
|
||||||
|
|||||||
@ -0,0 +1,22 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace Tests\Fixtures\Arch\ToUseStrictEquality;
|
||||||
|
|
||||||
|
class NotStrictEquality
|
||||||
|
{
|
||||||
|
public function test(): void
|
||||||
|
{
|
||||||
|
$a = 1;
|
||||||
|
$b = '1';
|
||||||
|
|
||||||
|
if ($a == $b) {
|
||||||
|
echo 'Equal';
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($a != $b) {
|
||||||
|
echo 'Equal';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
22
tests/Fixtures/Arch/ToUseStrictEquality/StrictEquality.php
Normal file
22
tests/Fixtures/Arch/ToUseStrictEquality/StrictEquality.php
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace Tests\Fixtures\Arch\ToUseStrictEquality;
|
||||||
|
|
||||||
|
class StrictEquality
|
||||||
|
{
|
||||||
|
public function test(): void
|
||||||
|
{
|
||||||
|
$a = 1;
|
||||||
|
$b = '1';
|
||||||
|
|
||||||
|
if ($a === $b) {
|
||||||
|
echo 'Equal';
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($a !== $b) {
|
||||||
|
echo 'Equal';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
5
tests/Fixtures/Arch/ToUseStrictTypes/HasNoStrictType.php
Normal file
5
tests/Fixtures/Arch/ToUseStrictTypes/HasNoStrictType.php
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Tests\Fixtures\Arch\ToUseStrictTypes;
|
||||||
|
|
||||||
|
class HasNoStrictType {}
|
||||||
7
tests/Fixtures/Arch/ToUseStrictTypes/HasStrictType.php
Normal file
7
tests/Fixtures/Arch/ToUseStrictTypes/HasStrictType.php
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace Tests\Fixtures\Arch\ToUseStrictTypes;
|
||||||
|
|
||||||
|
class HasStrictType {}
|
||||||
@ -0,0 +1,11 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
/** @noinspection PhpUnused */
|
||||||
|
|
||||||
|
// some other comment
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace Tests\Fixtures\Arch\ToUseStrictTypes;
|
||||||
|
|
||||||
|
class HasStrictTypeWithCommentsAbove {}
|
||||||
@ -6,7 +6,7 @@ use PHPUnit\Framework\TestCase;
|
|||||||
|
|
||||||
class ExampleTest extends TestCase
|
class ExampleTest extends TestCase
|
||||||
{
|
{
|
||||||
public function testExample()
|
public function test_example()
|
||||||
{
|
{
|
||||||
$this->markTestSkipped();
|
$this->markTestSkipped();
|
||||||
}
|
}
|
||||||
|
|||||||
@ -6,7 +6,7 @@ class ExampleTest extends Base\ExampleTest
|
|||||||
{
|
{
|
||||||
protected $foo;
|
protected $foo;
|
||||||
|
|
||||||
public function testExample()
|
public function test_example()
|
||||||
{
|
{
|
||||||
$this->assertTrue(true);
|
$this->assertTrue(true);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,23 +1,79 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
|
beforeEach(function () {
|
||||||
|
$this->ith = 0;
|
||||||
|
});
|
||||||
|
|
||||||
pest()->afterEach(function () {
|
pest()->afterEach(function () {
|
||||||
expect($this)
|
expect($this)
|
||||||
->toHaveProperty('ith')
|
->toHaveProperty('ith')
|
||||||
->and($this->ith)
|
->and($this->ith)
|
||||||
->toBe(1);
|
->toBe(3);
|
||||||
|
|
||||||
$this->ith = 2;
|
$this->ith++;
|
||||||
|
});
|
||||||
|
|
||||||
|
pest()->afterEach(function () {
|
||||||
|
expect($this)
|
||||||
|
->toHaveProperty('ith')
|
||||||
|
->and($this->ith)
|
||||||
|
->toBe(4);
|
||||||
|
|
||||||
|
$this->ith++;
|
||||||
});
|
});
|
||||||
|
|
||||||
afterEach(function () {
|
afterEach(function () {
|
||||||
expect($this)
|
expect($this)
|
||||||
->toHaveProperty('ith')
|
->toHaveProperty('ith')
|
||||||
->and($this->ith)
|
->and($this->ith)
|
||||||
->toBe(2);
|
->toBe(5);
|
||||||
|
|
||||||
|
$this->ith++;
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('nested', function () {
|
||||||
|
afterEach(function () {
|
||||||
|
expect($this)
|
||||||
|
->toHaveProperty('ith')
|
||||||
|
->and($this->ith)
|
||||||
|
->toBe(6);
|
||||||
|
|
||||||
|
$this->ith++;
|
||||||
|
});
|
||||||
|
|
||||||
|
test('nested afterEach execution order', function () {
|
||||||
|
expect($this)
|
||||||
|
->toHaveProperty('ith')
|
||||||
|
->and($this->ith)
|
||||||
|
->toBe(0);
|
||||||
|
|
||||||
|
$this->ith++;
|
||||||
|
});
|
||||||
|
|
||||||
|
afterEach(function () {
|
||||||
|
expect($this)
|
||||||
|
->toHaveProperty('ith')
|
||||||
|
->and($this->ith)
|
||||||
|
->toBe(7);
|
||||||
|
|
||||||
|
$this->ith++;
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
afterEach(function () {
|
||||||
|
expect($this)
|
||||||
|
->toHaveProperty('ith')
|
||||||
|
->and($this->ith)
|
||||||
|
->toBeBetween(6, 8);
|
||||||
|
|
||||||
|
$this->ith++;
|
||||||
});
|
});
|
||||||
|
|
||||||
test('global afterEach execution order', function () {
|
test('global afterEach execution order', function () {
|
||||||
expect($this)
|
expect($this)
|
||||||
->not()
|
->toHaveProperty('ith')
|
||||||
->toHaveProperty('ith');
|
->and($this->ith)
|
||||||
|
->toBe(0);
|
||||||
|
|
||||||
|
$this->ith++;
|
||||||
});
|
});
|
||||||
|
|||||||
@ -13,7 +13,7 @@ class ExecutedTest extends TestCase
|
|||||||
public static $executed = false;
|
public static $executed = false;
|
||||||
|
|
||||||
#[Test]
|
#[Test]
|
||||||
public function testThatGetsExecuted(): void
|
public function test_that_gets_executed(): void
|
||||||
{
|
{
|
||||||
self::$executed = true;
|
self::$executed = true;
|
||||||
|
|
||||||
|
|||||||
@ -17,7 +17,7 @@ class ParentTest extends TestCase
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[Test]
|
#[Test]
|
||||||
public function testOverrideMethod(): void
|
public function test_override_method(): void
|
||||||
{
|
{
|
||||||
assertTrue($this->getEntity() || true);
|
assertTrue($this->getEntity() || true);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -32,7 +32,12 @@ pest()
|
|||||||
$_SERVER['globalHook']->calls->beforeAll++;
|
$_SERVER['globalHook']->calls->beforeAll++;
|
||||||
})
|
})
|
||||||
->afterEach(function () {
|
->afterEach(function () {
|
||||||
$this->ith = 0;
|
if (! isset($this->ith)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
assert($this->ith === 1, 'Expected $this->ith to be 1, but got '.$this->ith);
|
||||||
|
$this->ith++;
|
||||||
})
|
})
|
||||||
->afterAll(function () {
|
->afterAll(function () {
|
||||||
$_SERVER['globalHook']->afterAll = 0;
|
$_SERVER['globalHook']->afterAll = 0;
|
||||||
@ -57,12 +62,12 @@ pest()->in('Hooks')
|
|||||||
$_SERVER['globalHook']->beforeAll = 1;
|
$_SERVER['globalHook']->beforeAll = 1;
|
||||||
})
|
})
|
||||||
->afterEach(function () {
|
->afterEach(function () {
|
||||||
expect($this)
|
if (! isset($this->ith)) {
|
||||||
->toHaveProperty('ith')
|
return;
|
||||||
->and($this->ith)
|
}
|
||||||
->toBe(0);
|
|
||||||
|
|
||||||
$this->ith = 1;
|
assert($this->ith === 2, 'Expected $this->ith to be 1, but got '.$this->ith);
|
||||||
|
$this->ith++;
|
||||||
})
|
})
|
||||||
->afterAll(function () {
|
->afterAll(function () {
|
||||||
expect($_SERVER['globalHook'])
|
expect($_SERVER['globalHook'])
|
||||||
|
|||||||
23
tests/Plugins/Coverage.php
Normal file
23
tests/Plugins/Coverage.php
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
use Pest\Plugins\Coverage;
|
||||||
|
use Symfony\Component\Console\Output\NullOutput;
|
||||||
|
|
||||||
|
test('compute comparable coverage', function (float $givenValue, float $expectedValue) {
|
||||||
|
$output = new NullOutput;
|
||||||
|
|
||||||
|
$plugin = new Coverage($output);
|
||||||
|
|
||||||
|
$comparableCoverage = (fn () => $this->computeComparableCoverage($givenValue))->call($plugin);
|
||||||
|
|
||||||
|
expect($comparableCoverage)->toBe($expectedValue);
|
||||||
|
})->with([
|
||||||
|
[0, 0],
|
||||||
|
[0.5, 0.5],
|
||||||
|
[1.0, 1.0],
|
||||||
|
[32.51, 32.5],
|
||||||
|
[32.12312321312312, 32.1],
|
||||||
|
[32.53333333333333, 32.5],
|
||||||
|
[32.57777771232132, 32.5],
|
||||||
|
[100.0, 100.0],
|
||||||
|
]);
|
||||||
@ -1,7 +1,7 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
it('creates a theme instance', function () {
|
it('creates a printer instance', function () {
|
||||||
$theme = pest()->theme();
|
$theme = pest()->printer();
|
||||||
|
|
||||||
expect($theme)->toBeInstanceOf(Pest\Configuration\Theme::class);
|
expect($theme)->toBeInstanceOf(Pest\Configuration\Printer::class);
|
||||||
});
|
});
|
||||||
|
|||||||
49
tests/Unit/Support/Arr.php
Normal file
49
tests/Unit/Support/Arr.php
Normal file
@ -0,0 +1,49 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
use Pest\Support\Arr;
|
||||||
|
|
||||||
|
describe('last', function () {
|
||||||
|
it('should return false for an empty arary', function () {
|
||||||
|
expect(Arr::last([]))->toBeFalse();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should return the last element for an array with a single element', function () {
|
||||||
|
expect(Arr::last([1]))->toBe(1);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should return the last element for an array without changing the internal pointer', function () {
|
||||||
|
$array = [1, 2, 3];
|
||||||
|
|
||||||
|
expect(Arr::last($array))->toBe(3);
|
||||||
|
expect(current($array))->toBe(1);
|
||||||
|
|
||||||
|
next($array);
|
||||||
|
expect(current($array))->toBe(2);
|
||||||
|
expect(Arr::last($array))->toBe(3);
|
||||||
|
expect(current($array))->toBe(2);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should return the last element for an associative array without changing the internal pointer', function () {
|
||||||
|
$array = ['first' => 1, 'second' => 2, 'third' => 3];
|
||||||
|
|
||||||
|
expect(Arr::last($array))->toBe(3);
|
||||||
|
expect(current($array))->toBe(1);
|
||||||
|
|
||||||
|
next($array);
|
||||||
|
expect(current($array))->toBe(2);
|
||||||
|
expect(Arr::last($array))->toBe(3);
|
||||||
|
expect(current($array))->toBe(2);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should return the last element for an mixed key array without changing the internal pointer', function () {
|
||||||
|
$array = ['first' => 1, 2, 'third' => 3];
|
||||||
|
|
||||||
|
expect(Arr::last($array))->toBe(3);
|
||||||
|
expect(current($array))->toBe(1);
|
||||||
|
|
||||||
|
next($array);
|
||||||
|
expect(current($array))->toBe(2);
|
||||||
|
expect(Arr::last($array))->toBe(3);
|
||||||
|
expect(current($array))->toBe(2);
|
||||||
|
});
|
||||||
|
});
|
||||||
@ -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('2')
|
->tests->toBe('3')
|
||||||
->assertions->toBe('2')
|
->assertions->toBe('3')
|
||||||
->errors->toBe('0')
|
->errors->toBe('0')
|
||||||
->failures->toBe('0')
|
->failures->toBe('0')
|
||||||
->skipped->toBe('0');
|
->skipped->toBe('0');
|
||||||
|
|||||||
@ -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, 17 todos, 19 skipped, 1078 passed (2591 assertions)')
|
->toContain('Tests: 2 deprecated, 4 warnings, 5 incomplete, 2 notices, 38 todos, 24 skipped, 1142 passed (2720 assertions)')
|
||||||
->toContain('Parallel: 3 processes');
|
->toContain('Parallel: 3 processes');
|
||||||
})->skipOnWindows();
|
})->skipOnWindows();
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user