mirror of
https://github.com/pestphp/pest.git
synced 2026-03-07 00:07:22 +01:00
Compare commits
63 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 12c75524a2 | |||
| 6edbd69dc4 | |||
| 0cfb1237e5 | |||
| cab6aa6e57 | |||
| 9ff2f3b46c | |||
| ead0237fb3 | |||
| 31726b51ad | |||
| 99d3ee448c | |||
| d21ae255f1 | |||
| 0823e5da88 | |||
| 1f913f6fc1 | |||
| a6dec31b9d | |||
| c1979f735f | |||
| 1c1cb1e591 | |||
| 49ddcbd66b | |||
| 23c8adf497 | |||
| 8e3d7d85e8 | |||
| 3cee6a499d | |||
| 3f38f19df8 | |||
| 4df6ab4a84 | |||
| 90b6771451 | |||
| 681723cbc3 | |||
| d9595ec122 | |||
| ec35010cf4 | |||
| d14f2728d8 | |||
| 152b7a9fc4 | |||
| 56ec3b9ee3 | |||
| ca69e4fd94 | |||
| 1965763cd0 | |||
| cd8d94780f | |||
| ba87e1fde8 | |||
| e48bd31ae4 | |||
| 5ae061d208 | |||
| 3d7e621b7d | |||
| bf14c4262a | |||
| b186d7a4ee | |||
| e109cd1da2 | |||
| 473f295b77 | |||
| a05684026e | |||
| 5df46d03c3 | |||
| 19424ae06d | |||
| 6c8970e0a3 | |||
| 2f2b51ce3d | |||
| 33f596bcce | |||
| 50a96dcb8f | |||
| d9a4fa33b9 | |||
| cc6bd59df9 | |||
| 3ce6408195 | |||
| 1c673fcff9 | |||
| ff82596158 | |||
| 0539d2ba62 | |||
| 221ac62f03 | |||
| 4b6c949032 | |||
| 1915ad368a | |||
| 1408cffc02 | |||
| 95b5379945 | |||
| a4833bbfe4 | |||
| cb1c777b9b | |||
| 7433cc5565 | |||
| 4c769fac66 | |||
| 176d3efbc6 | |||
| d635665c1b | |||
| 22467d05c8 |
42
.github/workflows/integration-tests.yml
vendored
Normal file
42
.github/workflows/integration-tests.yml
vendored
Normal file
@ -0,0 +1,42 @@
|
|||||||
|
name: Integration Tests
|
||||||
|
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
schedule:
|
||||||
|
- cron: '0 0 * * *'
|
||||||
|
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
ci:
|
||||||
|
if: github.event_name != 'schedule' || github.repository == 'pestphp/pest'
|
||||||
|
runs-on: ${{ matrix.os }}
|
||||||
|
strategy:
|
||||||
|
matrix:
|
||||||
|
os: [ubuntu-latest, macos-latest, windows-latest]
|
||||||
|
php: ['8.1', '8.2']
|
||||||
|
dependency-version: [prefer-lowest, prefer-stable]
|
||||||
|
|
||||||
|
name: PHP ${{ matrix.php }} - ${{ matrix.os }} - ${{ matrix.dependency-version }}
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- name: Checkout
|
||||||
|
uses: actions/checkout@v2
|
||||||
|
|
||||||
|
- name: Setup PHP
|
||||||
|
uses: shivammathur/setup-php@v2
|
||||||
|
with:
|
||||||
|
php-version: ${{ matrix.php }}
|
||||||
|
tools: composer:v2
|
||||||
|
coverage: none
|
||||||
|
|
||||||
|
- name: Setup Problem Matches
|
||||||
|
run: |
|
||||||
|
echo "::add-matcher::${{ runner.tool_cache }}/php.json"
|
||||||
|
echo "::add-matcher::${{ runner.tool_cache }}/phpunit.json"
|
||||||
|
|
||||||
|
- name: Install PHP dependencies
|
||||||
|
run: composer update --${{ matrix.dependency-version }} --no-interaction --no-progress --ansi
|
||||||
|
|
||||||
|
- name: Integration Tests
|
||||||
|
run: composer test:integration
|
||||||
|
|
||||||
1
.github/workflows/static.yml
vendored
1
.github/workflows/static.yml
vendored
@ -8,6 +8,7 @@ on:
|
|||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
static:
|
static:
|
||||||
|
if: github.event_name != 'schedule' || github.repository == 'pestphp/pest'
|
||||||
name: Static Tests
|
name: Static Tests
|
||||||
|
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
|
|||||||
4
.github/workflows/tests.yml
vendored
4
.github/workflows/tests.yml
vendored
@ -9,6 +9,7 @@ on:
|
|||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
ci:
|
ci:
|
||||||
|
if: github.event_name != 'schedule' || github.repository == 'pestphp/pest'
|
||||||
runs-on: ${{ matrix.os }}
|
runs-on: ${{ matrix.os }}
|
||||||
strategy:
|
strategy:
|
||||||
matrix:
|
matrix:
|
||||||
@ -43,6 +44,3 @@ jobs:
|
|||||||
- name: Unit Tests in Parallel
|
- name: Unit Tests in Parallel
|
||||||
run: composer test:parallel
|
run: composer test:parallel
|
||||||
if: startsWith(matrix.os, 'windows') != true
|
if: startsWith(matrix.os, 'windows') != true
|
||||||
|
|
||||||
- name: Integration Tests
|
|
||||||
run: composer test:integration
|
|
||||||
|
|||||||
44
CHANGELOG.md
44
CHANGELOG.md
@ -2,6 +2,50 @@
|
|||||||
|
|
||||||
## Unreleased
|
## Unreleased
|
||||||
|
|
||||||
|
## [v2.3.0 (2023-04-03)](https://github.com/pestphp/pest/compare/v2.3.0...v2.4.0)
|
||||||
|
|
||||||
|
### Added
|
||||||
|
- `skipOnWindows()`, `skipOnMac()`, and `skipOnLinux()` ([#757](https://github.com/pestphp/pest/pull/757))
|
||||||
|
- source architecture testing violation ([#1](https://github.com/pestphp/pest-plugin-arch/pull/1))((8e66263)[https://github.com/pestphp/pest-plugin-arch/commit/8e66263104304e99e3d6ceda25c7ed679b27fb03])
|
||||||
|
- `toHaveProperties` may now also check values ([#760](https://github.com/pestphp/pest/pull/760))
|
||||||
|
|
||||||
|
### Fixed
|
||||||
|
- Tests on `tests/Helpers` directory not being executed ([#753](https://github.com/pestphp/pest/pull/753))
|
||||||
|
- Teamcity count ([#747](https://github.com/pestphp/pest/pull/747))
|
||||||
|
- Parallel executation when class extends class with same name ([#748](https://github.com/pestphp/pest/pull/748))
|
||||||
|
- Wording on `uses()` hint ([#745](https://github.com/pestphp/pest/pull/745/files))
|
||||||
|
|
||||||
|
## [v2.3.0 (2023-03-28)](https://github.com/pestphp/pest/compare/v2.2.3...v2.3.0)
|
||||||
|
|
||||||
|
### Added
|
||||||
|
- Better error handler about missing uses ([#743](https://github.com/pestphp/pest/pull/743))
|
||||||
|
|
||||||
|
### Fixed
|
||||||
|
- Inconsistent spelling of `dataset` ([#739](https://github.com/pestphp/pest/pull/739))
|
||||||
|
|
||||||
|
### Chore
|
||||||
|
- Bumps PHPUnit to `^10.0.19` ([3d7e621](https://github.com/pestphp/pest/commit/3d7e621b7dfc03f0b2d9dcf6eb06c26bc383f502))
|
||||||
|
|
||||||
|
## [v2.2.3 (2023-03-24)](https://github.com/pestphp/pest/compare/v2.2.2...v2.2.3)
|
||||||
|
|
||||||
|
### Fixed
|
||||||
|
- Unnecessary dataset on dataset arguments missmatch ([#736](https://github.com/pestphp/pest/pull/736))
|
||||||
|
- Parallel arguments on plugins order ([#703](https://github.com/pestphp/pest/pull/703))
|
||||||
|
- Arch plugin runtime exceptions on bad phpdocs ([2f2b51c](https://github.com/pestphp/pest/commit/2f2b51ce3d1b000be9d6add0e785fd0044931b3b))
|
||||||
|
|
||||||
|
## [v2.2.2 (2023-03-23)](https://github.com/pestphp/pest/compare/v2.2.1...v2.2.2)
|
||||||
|
|
||||||
|
### Fixed
|
||||||
|
- Edge case in parallel executation test description ([3ce6408](https://github.com/pestphp/pest/commit/3ce640819541ca6022b250e000f336d87c3e7889))
|
||||||
|
|
||||||
|
## [v2.2.1 (2023-03-22)](https://github.com/pestphp/pest/compare/v2.2.0...v2.2.1)
|
||||||
|
|
||||||
|
### Fixed
|
||||||
|
- Collision between tests names with underscores ([#724](https://github.com/pestphp/pest/pull/724))
|
||||||
|
|
||||||
|
### Chore
|
||||||
|
- Bumps PHPUnit to `^10.0.18` ([1408cff](https://github.com/pestphp/pest/commit/1408cffc028690057e44f00038f9390f776e6bfb))
|
||||||
|
|
||||||
## [v2.2.0 (2023-03-22)](https://github.com/pestphp/pest/compare/v2.1.0...v2.2.0)
|
## [v2.2.0 (2023-03-22)](https://github.com/pestphp/pest/compare/v2.1.0...v2.2.0)
|
||||||
|
|
||||||
### Added
|
### Added
|
||||||
|
|||||||
@ -92,7 +92,7 @@ $bootPest = (static function (): void {
|
|||||||
exit;
|
exit;
|
||||||
}
|
}
|
||||||
|
|
||||||
$exitCode = $application->runTest(trim($testPath));
|
$exitCode = $application->runTest(realpath(trim($testPath)));
|
||||||
|
|
||||||
fwrite($statusFile, (string) $exitCode);
|
fwrite($statusFile, (string) $exitCode);
|
||||||
fflush($statusFile);
|
fflush($statusFile);
|
||||||
|
|||||||
@ -19,15 +19,15 @@
|
|||||||
"require": {
|
"require": {
|
||||||
"php": "^8.1.0",
|
"php": "^8.1.0",
|
||||||
"brianium/paratest": "^7.1.2",
|
"brianium/paratest": "^7.1.2",
|
||||||
"nunomaduro/collision": "^7.3.2",
|
"nunomaduro/collision": "^7.4.0",
|
||||||
"nunomaduro/termwind": "^1.15.1",
|
"nunomaduro/termwind": "^1.15.1",
|
||||||
"pestphp/pest-plugin": "^2.0.0",
|
"pestphp/pest-plugin": "^2.0.1",
|
||||||
"pestphp/pest-plugin-arch": "^2.0.1",
|
"pestphp/pest-plugin-arch": "^2.1.1",
|
||||||
"phpunit/phpunit": "^10.0.17"
|
"phpunit/phpunit": "^10.0.19"
|
||||||
},
|
},
|
||||||
"conflict": {
|
"conflict": {
|
||||||
"webmozart/assert": "<1.11.0",
|
"webmozart/assert": "<1.11.0",
|
||||||
"phpunit/phpunit": ">10.0.17"
|
"phpunit/phpunit": ">10.0.19"
|
||||||
},
|
},
|
||||||
"autoload": {
|
"autoload": {
|
||||||
"psr-4": {
|
"psr-4": {
|
||||||
@ -41,6 +41,7 @@
|
|||||||
"autoload-dev": {
|
"autoload-dev": {
|
||||||
"psr-4": {
|
"psr-4": {
|
||||||
"Tests\\Fixtures\\Covers\\": "tests/Fixtures/Covers",
|
"Tests\\Fixtures\\Covers\\": "tests/Fixtures/Covers",
|
||||||
|
"Tests\\Fixtures\\Inheritance\\": "tests/Fixtures/Inheritance",
|
||||||
"Tests\\": "tests/PHPUnit/"
|
"Tests\\": "tests/PHPUnit/"
|
||||||
},
|
},
|
||||||
"files": [
|
"files": [
|
||||||
@ -48,8 +49,8 @@
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
"require-dev": {
|
"require-dev": {
|
||||||
"pestphp/pest-dev-tools": "^2.5.0",
|
"pestphp/pest-dev-tools": "^2.6.0",
|
||||||
"symfony/process": "^6.2.7"
|
"symfony/process": "^6.2.8"
|
||||||
},
|
},
|
||||||
"minimum-stability": "stable",
|
"minimum-stability": "stable",
|
||||||
"config": {
|
"config": {
|
||||||
|
|||||||
@ -2,7 +2,7 @@ ARG PHP=8.1
|
|||||||
FROM php:${PHP}-cli-alpine
|
FROM php:${PHP}-cli-alpine
|
||||||
|
|
||||||
RUN apk update \
|
RUN apk update \
|
||||||
&& apk add zip libzip-dev icu-dev
|
&& apk add zip libzip-dev icu-dev git
|
||||||
|
|
||||||
RUN docker-php-ext-configure zip
|
RUN docker-php-ext-configure zip
|
||||||
RUN docker-php-ext-install zip
|
RUN docker-php-ext-install zip
|
||||||
|
|||||||
56
overrides/Event/Value/ThrowableBuilder.php
Normal file
56
overrides/Event/Value/ThrowableBuilder.php
Normal file
@ -0,0 +1,56 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This file is part of PHPUnit.
|
||||||
|
*
|
||||||
|
* (c) Sebastian Bergmann <sebastian@phpunit.de>
|
||||||
|
*
|
||||||
|
* For the full copyright and license information, please view the LICENSE
|
||||||
|
* file that was distributed with this source code.
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace PHPUnit\Event\Code;
|
||||||
|
|
||||||
|
use NunoMaduro\Collision\Contracts\RenderableOnCollisionEditor;
|
||||||
|
use PHPUnit\Event\NoPreviousThrowableException;
|
||||||
|
use PHPUnit\Framework\Exception;
|
||||||
|
use PHPUnit\Util\Filter;
|
||||||
|
use PHPUnit\Util\ThrowableToStringMapper;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @internal This class is not covered by the backward compatibility promise for PHPUnit
|
||||||
|
*/
|
||||||
|
final class ThrowableBuilder
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* @throws Exception
|
||||||
|
* @throws NoPreviousThrowableException
|
||||||
|
*/
|
||||||
|
public static function from(\Throwable $t): Throwable
|
||||||
|
{
|
||||||
|
$previous = $t->getPrevious();
|
||||||
|
|
||||||
|
if ($previous !== null) {
|
||||||
|
$previous = self::from($previous);
|
||||||
|
}
|
||||||
|
|
||||||
|
$trace = Filter::getFilteredStacktrace($t);
|
||||||
|
|
||||||
|
if ($t instanceof RenderableOnCollisionEditor && $frame = $t->toCollisionEditor()) {
|
||||||
|
$file = $frame->getFile();
|
||||||
|
$line = $frame->getLine();
|
||||||
|
|
||||||
|
$trace = "$file:$line\n$trace";
|
||||||
|
}
|
||||||
|
|
||||||
|
return new Throwable(
|
||||||
|
$t::class,
|
||||||
|
$t->getMessage(),
|
||||||
|
ThrowableToStringMapper::map($t),
|
||||||
|
$trace,
|
||||||
|
$previous
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -107,7 +107,7 @@ final class NameFilterIterator extends RecursiveFilterIterator
|
|||||||
if (preg_match('/^(.*?)#(\d+)(?:-(\d+))?$/', $filter, $matches)) {
|
if (preg_match('/^(.*?)#(\d+)(?:-(\d+))?$/', $filter, $matches)) {
|
||||||
if (isset($matches[3]) && $matches[2] < $matches[3]) {
|
if (isset($matches[3]) && $matches[2] < $matches[3]) {
|
||||||
$filter = sprintf(
|
$filter = sprintf(
|
||||||
'%s.*with data set #(\d+)$',
|
'%s.*with dataset #(\d+)$',
|
||||||
$matches[1]
|
$matches[1]
|
||||||
);
|
);
|
||||||
|
|
||||||
@ -115,7 +115,7 @@ final class NameFilterIterator extends RecursiveFilterIterator
|
|||||||
$this->filterMax = (int) $matches[3];
|
$this->filterMax = (int) $matches[3];
|
||||||
} else {
|
} else {
|
||||||
$filter = sprintf(
|
$filter = sprintf(
|
||||||
'%s.*with data set #%s$',
|
'%s.*with dataset #%s$',
|
||||||
$matches[1],
|
$matches[1],
|
||||||
$matches[2]
|
$matches[2]
|
||||||
);
|
);
|
||||||
@ -125,7 +125,7 @@ final class NameFilterIterator extends RecursiveFilterIterator
|
|||||||
// * testDetermineJsonError@JSON.*
|
// * testDetermineJsonError@JSON.*
|
||||||
elseif (preg_match('/^(.*?)@(.+)$/', $filter, $matches)) {
|
elseif (preg_match('/^(.*?)@(.+)$/', $filter, $matches)) {
|
||||||
$filter = sprintf(
|
$filter = sprintf(
|
||||||
'%s.*with data set "%s"$',
|
'%s.*with dataset "%s"$',
|
||||||
$matches[1],
|
$matches[1],
|
||||||
$matches[2]
|
$matches[2]
|
||||||
);
|
);
|
||||||
|
|||||||
@ -18,6 +18,7 @@
|
|||||||
<directory suffix=".php">./tests</directory>
|
<directory suffix=".php">./tests</directory>
|
||||||
<exclude>./tests/.snapshots</exclude>
|
<exclude>./tests/.snapshots</exclude>
|
||||||
<exclude>./tests/.tests</exclude>
|
<exclude>./tests/.tests</exclude>
|
||||||
|
<exclude>./tests/Fixtures/Inheritance</exclude>
|
||||||
</testsuite>
|
</testsuite>
|
||||||
</testsuites>
|
</testsuites>
|
||||||
<coverage>
|
<coverage>
|
||||||
|
|||||||
@ -24,6 +24,7 @@ final class BootOverrides implements Bootstrapper
|
|||||||
'TextUI/Command/WarmCodeCoverageCacheCommand.php',
|
'TextUI/Command/WarmCodeCoverageCacheCommand.php',
|
||||||
'TextUI/Output/Default/ProgressPrinter/TestSkippedSubscriber.php',
|
'TextUI/Output/Default/ProgressPrinter/TestSkippedSubscriber.php',
|
||||||
'TextUI/TestSuiteFilterProcessor.php',
|
'TextUI/TestSuiteFilterProcessor.php',
|
||||||
|
'Event/Value/ThrowableBuilder.php',
|
||||||
];
|
];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@ -241,7 +241,7 @@ trait Testable
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (in_array($testParameterTypes[$argumentIndex], [\Closure::class, 'callable', 'mixed'])) {
|
if (in_array($testParameterTypes[$argumentIndex], [Closure::class, 'callable', 'mixed'])) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -255,7 +255,7 @@ trait Testable
|
|||||||
return $arguments;
|
return $arguments;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (in_array($testParameterTypes[0], [\Closure::class, 'callable'])) {
|
if (in_array($testParameterTypes[0], [Closure::class, 'callable'])) {
|
||||||
return $arguments;
|
return $arguments;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -291,7 +291,7 @@ trait Testable
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
throw new DatasetArgsCountMismatch($this->dataName(), $requiredParametersCount, $suppliedParametersCount);
|
throw new DatasetArgsCountMismatch($requiredParametersCount, $suppliedParametersCount);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@ -10,7 +10,7 @@ namespace Pest\Contracts\Plugins;
|
|||||||
interface HandlesArguments
|
interface HandlesArguments
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* Adds arguments before of the Test Suite execution.
|
* Adds arguments before the Test Suite execution.
|
||||||
*
|
*
|
||||||
* @param array<int, string> $arguments
|
* @param array<int, string> $arguments
|
||||||
* @return array<int, string>
|
* @return array<int, string>
|
||||||
|
|||||||
@ -8,8 +8,8 @@ use Exception;
|
|||||||
|
|
||||||
final class DatasetArgsCountMismatch extends Exception
|
final class DatasetArgsCountMismatch extends Exception
|
||||||
{
|
{
|
||||||
public function __construct(string $dataName, int $requiredCount, int $suppliedCount)
|
public function __construct(int $requiredCount, int $suppliedCount)
|
||||||
{
|
{
|
||||||
parent::__construct(sprintf('Test expects %d arguments but dataset [%s] only provides %d', $requiredCount, $dataName, $suppliedCount));
|
parent::__construct(sprintf('Test expects %d arguments but dataset only provides %d', $requiredCount, $suppliedCount));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -166,6 +166,14 @@ final class Converter
|
|||||||
return $this->toRelativePath($path);
|
return $this->toRelativePath($path);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the test suite size.
|
||||||
|
*/
|
||||||
|
public function getTestSuiteSize(TestSuite $testSuite): int
|
||||||
|
{
|
||||||
|
return $testSuite->count();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Transforms the given path in relative path.
|
* Transforms the given path in relative path.
|
||||||
*/
|
*/
|
||||||
|
|||||||
@ -40,6 +40,13 @@ final class ServiceMessage
|
|||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static function testSuiteCount(int $count): self
|
||||||
|
{
|
||||||
|
return new self('testCount', [
|
||||||
|
'count' => $count,
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
public static function testSuiteFinished(string $name): self
|
public static function testSuiteFinished(string $name): self
|
||||||
{
|
{
|
||||||
return new self('testSuiteFinished', [
|
return new self('testSuiteFinished', [
|
||||||
|
|||||||
@ -44,6 +44,8 @@ final class TeamCityLogger
|
|||||||
{
|
{
|
||||||
private ?HRTime $time = null;
|
private ?HRTime $time = null;
|
||||||
|
|
||||||
|
private bool $isSummaryTestCountPrinted = false;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @throws EventFacadeIsSealedException
|
* @throws EventFacadeIsSealedException
|
||||||
* @throws UnknownSubscriberTypeException
|
* @throws UnknownSubscriberTypeException
|
||||||
@ -66,6 +68,15 @@ final class TeamCityLogger
|
|||||||
);
|
);
|
||||||
|
|
||||||
$this->output($message);
|
$this->output($message);
|
||||||
|
|
||||||
|
if (! $this->isSummaryTestCountPrinted) {
|
||||||
|
$this->isSummaryTestCountPrinted = true;
|
||||||
|
$message = ServiceMessage::testSuiteCount(
|
||||||
|
$this->converter->getTestSuiteSize($event->testSuite())
|
||||||
|
);
|
||||||
|
|
||||||
|
$this->output($message);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testSuiteFinished(TestSuiteFinished $event): void
|
public function testSuiteFinished(TestSuiteFinished $event): void
|
||||||
|
|||||||
@ -296,8 +296,8 @@ final class Expectation
|
|||||||
*/
|
*/
|
||||||
public function toHaveProperties(iterable $names, string $message = ''): self
|
public function toHaveProperties(iterable $names, string $message = ''): self
|
||||||
{
|
{
|
||||||
foreach ($names as $name) {
|
foreach ($names as $name => $value) {
|
||||||
$this->toHaveProperty($name, message: $message);
|
is_int($name) ? $this->toHaveProperty($value, message: $message) : $this->toHaveProperty($name, $value, $message);
|
||||||
}
|
}
|
||||||
|
|
||||||
return $this;
|
return $this;
|
||||||
|
|||||||
@ -172,6 +172,40 @@ final class TestCall
|
|||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Skips the current test if the given test is running on Windows.
|
||||||
|
*/
|
||||||
|
public function skipOnWindows(): self
|
||||||
|
{
|
||||||
|
return $this->skipOn('Windows', 'This test is skipped on [Windows].');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Skips the current test if the given test is running on Mac OS.
|
||||||
|
*/
|
||||||
|
public function skipOnMac(): self
|
||||||
|
{
|
||||||
|
return $this->skipOn('Darwin', 'This test is skipped on [Mac].');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Skips the current test if the given test is running on Linux.
|
||||||
|
*/
|
||||||
|
public function skipOnLinux(): self
|
||||||
|
{
|
||||||
|
return $this->skipOn('Linux', 'This test is skipped on [Linux].');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Skips the current test if the given test is running on the given operating systems.
|
||||||
|
*/
|
||||||
|
private function skipOn(string $osFamily, string $message): self
|
||||||
|
{
|
||||||
|
return PHP_OS_FAMILY === $osFamily
|
||||||
|
? $this->skip($message)
|
||||||
|
: $this;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the test as "todo".
|
* Sets the test as "todo".
|
||||||
*/
|
*/
|
||||||
|
|||||||
@ -6,7 +6,7 @@ namespace Pest;
|
|||||||
|
|
||||||
function version(): string
|
function version(): string
|
||||||
{
|
{
|
||||||
return '2.2.0';
|
return '2.4.0';
|
||||||
}
|
}
|
||||||
|
|
||||||
function testDirectory(string $file = ''): string
|
function testDirectory(string $file = ''): string
|
||||||
|
|||||||
@ -14,15 +14,16 @@ use Pest\Support\Arr;
|
|||||||
use Pest\Support\Container;
|
use Pest\Support\Container;
|
||||||
use Pest\TestSuite;
|
use Pest\TestSuite;
|
||||||
use function Pest\version;
|
use function Pest\version;
|
||||||
|
use Stringable;
|
||||||
use Symfony\Component\Console\Application;
|
use Symfony\Component\Console\Application;
|
||||||
use Symfony\Component\Console\Command\Command;
|
|
||||||
use Symfony\Component\Console\Input\ArgvInput;
|
use Symfony\Component\Console\Input\ArgvInput;
|
||||||
use Symfony\Component\Console\Output\OutputInterface;
|
|
||||||
|
|
||||||
final class Parallel implements HandlesArguments
|
final class Parallel implements HandlesArguments
|
||||||
{
|
{
|
||||||
use HandleArguments;
|
use HandleArguments;
|
||||||
|
|
||||||
|
private const GLOBAL_PREFIX = 'PEST_PARALLEL_GLOBAL_';
|
||||||
|
|
||||||
private const HANDLERS = [
|
private const HANDLERS = [
|
||||||
Parallel\Handlers\Parallel::class,
|
Parallel\Handlers\Parallel::class,
|
||||||
Parallel\Handlers\Pest::class,
|
Parallel\Handlers\Pest::class,
|
||||||
@ -59,6 +60,33 @@ final class Parallel implements HandlesArguments
|
|||||||
return ((int) $argvValue) === 1;
|
return ((int) $argvValue) === 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets a global value that can be accessed by the parent process and all workers.
|
||||||
|
*/
|
||||||
|
public static function setGlobal(string $key, string|int|bool|Stringable $value): void
|
||||||
|
{
|
||||||
|
$data = ['value' => $value instanceof Stringable ? $value->__toString() : $value];
|
||||||
|
|
||||||
|
$_ENV[self::GLOBAL_PREFIX.$key] = json_encode($data, JSON_THROW_ON_ERROR);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the given global value if one has been set.
|
||||||
|
*/
|
||||||
|
public static function getGlobal(string $key): string|int|bool|null
|
||||||
|
{
|
||||||
|
$placesToCheck = [$_SERVER, $_ENV];
|
||||||
|
|
||||||
|
foreach ($placesToCheck as $location) {
|
||||||
|
if (array_key_exists(self::GLOBAL_PREFIX.$key, $location)) {
|
||||||
|
// @phpstan-ignore-next-line
|
||||||
|
return json_decode((string) $location[self::GLOBAL_PREFIX.$key], true, 512, JSON_THROW_ON_ERROR)['value'] ?? null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* {@inheritdoc}
|
* {@inheritdoc}
|
||||||
*/
|
*/
|
||||||
@ -86,12 +114,6 @@ final class Parallel implements HandlesArguments
|
|||||||
*/
|
*/
|
||||||
private function runTestSuiteInParallel(array $arguments): int
|
private function runTestSuiteInParallel(array $arguments): int
|
||||||
{
|
{
|
||||||
if (! class_exists(ParaTestCommand::class)) {
|
|
||||||
$this->askUserToInstallParatest();
|
|
||||||
|
|
||||||
return Command::FAILURE;
|
|
||||||
}
|
|
||||||
|
|
||||||
$handlers = array_filter(
|
$handlers = array_filter(
|
||||||
array_map(fn ($handler): object|string => Container::getInstance()->get($handler), self::HANDLERS),
|
array_map(fn ($handler): object|string => Container::getInstance()->get($handler), self::HANDLERS),
|
||||||
fn ($handler): bool => $handler instanceof HandlesArguments,
|
fn ($handler): bool => $handler instanceof HandlesArguments,
|
||||||
@ -128,20 +150,6 @@ final class Parallel implements HandlesArguments
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Outputs a message to the user asking them to install ParaTest as a dev dependency.
|
|
||||||
*/
|
|
||||||
private function askUserToInstallParatest(): void
|
|
||||||
{
|
|
||||||
/** @var OutputInterface $output */
|
|
||||||
$output = Container::getInstance()->get(OutputInterface::class);
|
|
||||||
|
|
||||||
$output->writeln([
|
|
||||||
'<fg=red>Pest Parallel requires ParaTest to run.</>',
|
|
||||||
'Please run <fg=yellow>composer require --dev brianium/paratest</>.',
|
|
||||||
]);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Builds an instance of the Paratest command.
|
* Builds an instance of the Paratest command.
|
||||||
*/
|
*/
|
||||||
|
|||||||
@ -235,6 +235,6 @@ final class DatasetsRepository
|
|||||||
return sprintf('(%s)', $exporter->shortenedRecursiveExport($data));
|
return sprintf('(%s)', $exporter->shortenedRecursiveExport($data));
|
||||||
}
|
}
|
||||||
|
|
||||||
return sprintf('data set "%s"', $key);
|
return sprintf('dataset "%s"', $key);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -30,7 +30,10 @@ final class Backtrace
|
|||||||
|
|
||||||
$traceFile = str_replace(DIRECTORY_SEPARATOR, '/', $trace[self::FILE]);
|
$traceFile = str_replace(DIRECTORY_SEPARATOR, '/', $trace[self::FILE]);
|
||||||
|
|
||||||
if (Str::endsWith($traceFile, 'overrides/Runner/TestSuiteLoader.php')) {
|
if (
|
||||||
|
Str::endsWith($traceFile, 'overrides/Runner/TestSuiteLoader.php') ||
|
||||||
|
Str::endsWith($traceFile, 'src/Bootstrappers/BootFiles.php')
|
||||||
|
) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -5,6 +5,7 @@ declare(strict_types=1);
|
|||||||
namespace Pest\Support;
|
namespace Pest\Support;
|
||||||
|
|
||||||
use Closure;
|
use Closure;
|
||||||
|
use PHPUnit\Framework\TestCase;
|
||||||
use Throwable;
|
use Throwable;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -15,8 +16,7 @@ final class ExceptionTrace
|
|||||||
private const UNDEFINED_METHOD = 'Call to undefined method P\\';
|
private const UNDEFINED_METHOD = 'Call to undefined method P\\';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Ensures the given closure reports
|
* Ensures the given closure reports the good execution context.
|
||||||
* the good execution context.
|
|
||||||
*
|
*
|
||||||
* @return mixed
|
* @return mixed
|
||||||
*
|
*
|
||||||
@ -28,8 +28,14 @@ final class ExceptionTrace
|
|||||||
return $closure();
|
return $closure();
|
||||||
} catch (Throwable $throwable) {
|
} catch (Throwable $throwable) {
|
||||||
if (Str::startsWith($message = $throwable->getMessage(), self::UNDEFINED_METHOD)) {
|
if (Str::startsWith($message = $throwable->getMessage(), self::UNDEFINED_METHOD)) {
|
||||||
|
$class = preg_match('/^Call to undefined method ([^:]+)::/', $message, $matches) === false ? null : $matches[1];
|
||||||
|
|
||||||
$message = str_replace(self::UNDEFINED_METHOD, 'Call to undefined method ', $message);
|
$message = str_replace(self::UNDEFINED_METHOD, 'Call to undefined method ', $message);
|
||||||
|
|
||||||
|
if (class_exists($class) && count(class_parents($class)) > 0 && array_values(class_parents($class))[0] === TestCase::class) {
|
||||||
|
$message .= '. Did you forget to use the [uses()] function? Read more at: https://pestphp.com/docs/configuring-tests';
|
||||||
|
}
|
||||||
|
|
||||||
Reflection::setPropertyValue($throwable, 'message', $message);
|
Reflection::setPropertyValue($throwable, 'message', $message);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -24,7 +24,7 @@ final class StateGenerator
|
|||||||
|
|
||||||
foreach ($testResult->testErroredEvents() as $testResultEvent) {
|
foreach ($testResult->testErroredEvents() as $testResultEvent) {
|
||||||
if ($testResultEvent instanceof Errored) {
|
if ($testResultEvent instanceof Errored) {
|
||||||
$state->add(TestResult::fromTestCase(
|
$state->add(TestResult::fromPestParallelTestCase(
|
||||||
$testResultEvent->test(),
|
$testResultEvent->test(),
|
||||||
TestResult::FAIL,
|
TestResult::FAIL,
|
||||||
$testResultEvent->throwable()
|
$testResultEvent->throwable()
|
||||||
@ -35,7 +35,7 @@ final class StateGenerator
|
|||||||
}
|
}
|
||||||
|
|
||||||
foreach ($testResult->testFailedEvents() as $testResultEvent) {
|
foreach ($testResult->testFailedEvents() as $testResultEvent) {
|
||||||
$state->add(TestResult::fromTestCase(
|
$state->add(TestResult::fromPestParallelTestCase(
|
||||||
$testResultEvent->test(),
|
$testResultEvent->test(),
|
||||||
TestResult::FAIL,
|
TestResult::FAIL,
|
||||||
$testResultEvent->throwable()
|
$testResultEvent->throwable()
|
||||||
@ -43,7 +43,7 @@ final class StateGenerator
|
|||||||
}
|
}
|
||||||
|
|
||||||
foreach ($testResult->testMarkedIncompleteEvents() as $testResultEvent) {
|
foreach ($testResult->testMarkedIncompleteEvents() as $testResultEvent) {
|
||||||
$state->add(TestResult::fromTestCase(
|
$state->add(TestResult::fromPestParallelTestCase(
|
||||||
$testResultEvent->test(),
|
$testResultEvent->test(),
|
||||||
TestResult::INCOMPLETE,
|
TestResult::INCOMPLETE,
|
||||||
$testResultEvent->throwable()
|
$testResultEvent->throwable()
|
||||||
@ -52,7 +52,7 @@ final class StateGenerator
|
|||||||
|
|
||||||
foreach ($testResult->testConsideredRiskyEvents() as $riskyEvents) {
|
foreach ($testResult->testConsideredRiskyEvents() as $riskyEvents) {
|
||||||
foreach ($riskyEvents as $riskyEvent) {
|
foreach ($riskyEvents as $riskyEvent) {
|
||||||
$state->add(TestResult::fromTestCase(
|
$state->add(TestResult::fromPestParallelTestCase(
|
||||||
$riskyEvent->test(),
|
$riskyEvent->test(),
|
||||||
TestResult::RISKY,
|
TestResult::RISKY,
|
||||||
ThrowableBuilder::from(new TestOutcome($riskyEvent->message()))
|
ThrowableBuilder::from(new TestOutcome($riskyEvent->message()))
|
||||||
@ -62,12 +62,12 @@ final class StateGenerator
|
|||||||
|
|
||||||
foreach ($testResult->testSkippedEvents() as $testResultEvent) {
|
foreach ($testResult->testSkippedEvents() as $testResultEvent) {
|
||||||
if ($testResultEvent->message() === '__TODO__') {
|
if ($testResultEvent->message() === '__TODO__') {
|
||||||
$state->add(TestResult::fromTestCase($testResultEvent->test(), TestResult::TODO));
|
$state->add(TestResult::fromPestParallelTestCase($testResultEvent->test(), TestResult::TODO));
|
||||||
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
$state->add(TestResult::fromTestCase(
|
$state->add(TestResult::fromPestParallelTestCase(
|
||||||
$testResultEvent->test(),
|
$testResultEvent->test(),
|
||||||
TestResult::SKIPPED,
|
TestResult::SKIPPED,
|
||||||
ThrowableBuilder::from(new SkippedWithMessageException($testResultEvent->message()))
|
ThrowableBuilder::from(new SkippedWithMessageException($testResultEvent->message()))
|
||||||
@ -77,7 +77,7 @@ final class StateGenerator
|
|||||||
foreach ($testResult->testTriggeredDeprecationEvents() as $testResultEvent) {
|
foreach ($testResult->testTriggeredDeprecationEvents() as $testResultEvent) {
|
||||||
$testResultEvent = $testResultEvent[0];
|
$testResultEvent = $testResultEvent[0];
|
||||||
|
|
||||||
$state->add(TestResult::fromTestCase(
|
$state->add(TestResult::fromPestParallelTestCase(
|
||||||
$testResultEvent->test(),
|
$testResultEvent->test(),
|
||||||
TestResult::DEPRECATED,
|
TestResult::DEPRECATED,
|
||||||
ThrowableBuilder::from(new TestOutcome($testResultEvent->message()))
|
ThrowableBuilder::from(new TestOutcome($testResultEvent->message()))
|
||||||
@ -87,7 +87,7 @@ final class StateGenerator
|
|||||||
foreach ($testResult->testTriggeredPhpDeprecationEvents() as $testResultEvent) {
|
foreach ($testResult->testTriggeredPhpDeprecationEvents() as $testResultEvent) {
|
||||||
$testResultEvent = $testResultEvent[0];
|
$testResultEvent = $testResultEvent[0];
|
||||||
|
|
||||||
$state->add(TestResult::fromTestCase(
|
$state->add(TestResult::fromPestParallelTestCase(
|
||||||
$testResultEvent->test(),
|
$testResultEvent->test(),
|
||||||
TestResult::DEPRECATED,
|
TestResult::DEPRECATED,
|
||||||
ThrowableBuilder::from(new TestOutcome($testResultEvent->message()))
|
ThrowableBuilder::from(new TestOutcome($testResultEvent->message()))
|
||||||
@ -97,7 +97,7 @@ final class StateGenerator
|
|||||||
foreach ($testResult->testTriggeredNoticeEvents() as $testResultEvent) {
|
foreach ($testResult->testTriggeredNoticeEvents() as $testResultEvent) {
|
||||||
$testResultEvent = $testResultEvent[0];
|
$testResultEvent = $testResultEvent[0];
|
||||||
|
|
||||||
$state->add(TestResult::fromTestCase(
|
$state->add(TestResult::fromPestParallelTestCase(
|
||||||
$testResultEvent->test(),
|
$testResultEvent->test(),
|
||||||
TestResult::NOTICE,
|
TestResult::NOTICE,
|
||||||
ThrowableBuilder::from(new TestOutcome($testResultEvent->message()))
|
ThrowableBuilder::from(new TestOutcome($testResultEvent->message()))
|
||||||
@ -107,7 +107,7 @@ final class StateGenerator
|
|||||||
foreach ($testResult->testTriggeredPhpNoticeEvents() as $testResultEvent) {
|
foreach ($testResult->testTriggeredPhpNoticeEvents() as $testResultEvent) {
|
||||||
$testResultEvent = $testResultEvent[0];
|
$testResultEvent = $testResultEvent[0];
|
||||||
|
|
||||||
$state->add(TestResult::fromTestCase(
|
$state->add(TestResult::fromPestParallelTestCase(
|
||||||
$testResultEvent->test(),
|
$testResultEvent->test(),
|
||||||
TestResult::NOTICE,
|
TestResult::NOTICE,
|
||||||
ThrowableBuilder::from(new TestOutcome($testResultEvent->message()))
|
ThrowableBuilder::from(new TestOutcome($testResultEvent->message()))
|
||||||
@ -117,7 +117,7 @@ final class StateGenerator
|
|||||||
foreach ($testResult->testTriggeredWarningEvents() as $testResultEvent) {
|
foreach ($testResult->testTriggeredWarningEvents() as $testResultEvent) {
|
||||||
$testResultEvent = $testResultEvent[0];
|
$testResultEvent = $testResultEvent[0];
|
||||||
|
|
||||||
$state->add(TestResult::fromTestCase(
|
$state->add(TestResult::fromPestParallelTestCase(
|
||||||
$testResultEvent->test(),
|
$testResultEvent->test(),
|
||||||
TestResult::WARN,
|
TestResult::WARN,
|
||||||
ThrowableBuilder::from(new TestOutcome($testResultEvent->message()))
|
ThrowableBuilder::from(new TestOutcome($testResultEvent->message()))
|
||||||
@ -127,7 +127,7 @@ final class StateGenerator
|
|||||||
foreach ($testResult->testTriggeredPhpWarningEvents() as $testResultEvent) {
|
foreach ($testResult->testTriggeredPhpWarningEvents() as $testResultEvent) {
|
||||||
$testResultEvent = $testResultEvent[0];
|
$testResultEvent = $testResultEvent[0];
|
||||||
|
|
||||||
$state->add(TestResult::fromTestCase(
|
$state->add(TestResult::fromPestParallelTestCase(
|
||||||
$testResultEvent->test(),
|
$testResultEvent->test(),
|
||||||
TestResult::WARN,
|
TestResult::WARN,
|
||||||
ThrowableBuilder::from(new TestOutcome($testResultEvent->message()))
|
ThrowableBuilder::from(new TestOutcome($testResultEvent->message()))
|
||||||
@ -136,7 +136,7 @@ final class StateGenerator
|
|||||||
|
|
||||||
// for each test that passed, we need to add it to the state
|
// for each test that passed, we need to add it to the state
|
||||||
for ($i = 0; $i < $passedTests; $i++) {
|
for ($i = 0; $i < $passedTests; $i++) {
|
||||||
$state->add(TestResult::fromTestCase(
|
$state->add(TestResult::fromPestParallelTestCase(
|
||||||
new TestMethod(
|
new TestMethod(
|
||||||
"$i", // @phpstan-ignore-line
|
"$i", // @phpstan-ignore-line
|
||||||
'', // @phpstan-ignore-line
|
'', // @phpstan-ignore-line
|
||||||
|
|||||||
@ -59,6 +59,8 @@ final class Str
|
|||||||
*/
|
*/
|
||||||
public static function evaluable(string $code): string
|
public static function evaluable(string $code): string
|
||||||
{
|
{
|
||||||
|
$code = str_replace('_', '__', $code);
|
||||||
|
|
||||||
$code = self::PREFIX.str_replace(' ', '_', $code);
|
$code = self::PREFIX.str_replace(' ', '_', $code);
|
||||||
|
|
||||||
// sticks to PHP8.2 function naming rules https://www.php.net/manual/en/functions.user-defined.php
|
// sticks to PHP8.2 function naming rules https://www.php.net/manual/en/functions.user-defined.php
|
||||||
|
|||||||
@ -1,4 +1,5 @@
|
|||||||
##teamcity[testSuiteStarted name='Tests/tests/Failure' locationHint='file://tests/.tests/Failure.php' flowId='1234']
|
##teamcity[testSuiteStarted name='Tests/tests/Failure' locationHint='file://tests/.tests/Failure.php' flowId='1234']
|
||||||
|
##teamcity[testCount count='6' 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 src/Mixins/Expectation.php:343|nat src/Support/ExpectationPipeline.php:75|nat src/Support/ExpectationPipeline.php:79|nat src/Expectation.php:300|nat tests/.tests/Failure.php:6|nat src/Factories/TestCaseMethodFactory.php:100|nat src/Concerns/Testable.php:302|nat src/Support/ExceptionTrace.php:28|nat src/Concerns/Testable.php:302|nat src/Concerns/Testable.php:221|nat src/Kernel.php:86' 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 src/Mixins/Expectation.php:343|nat src/Support/ExpectationPipeline.php:75|nat src/Support/ExpectationPipeline.php:79|nat src/Expectation.php:300|nat tests/.tests/Failure.php:6|nat src/Factories/TestCaseMethodFactory.php:100|nat src/Concerns/Testable.php:302|nat src/Support/ExceptionTrace.php:28|nat src/Concerns/Testable.php:302|nat src/Concerns/Testable.php:221|nat src/Kernel.php:86' type='comparisonFailure' actual='true' expected='false' flowId='1234']
|
||||||
##teamcity[testFinished name='it can fail with comparison' duration='100000' flowId='1234']
|
##teamcity[testFinished name='it can fail with comparison' duration='100000' flowId='1234']
|
||||||
|
|||||||
@ -1,4 +1,5 @@
|
|||||||
##teamcity[testSuiteStarted name='Tests/tests/SuccessOnly' locationHint='file://tests/.tests/SuccessOnly.php' flowId='1234']
|
##teamcity[testSuiteStarted name='Tests/tests/SuccessOnly' locationHint='file://tests/.tests/SuccessOnly.php' flowId='1234']
|
||||||
|
##teamcity[testCount count='2' flowId='1234']
|
||||||
##teamcity[testStarted name='it can pass with comparison' locationHint='pest_qn://tests/.tests/SuccessOnly.php::it can pass with comparison' flowId='1234']
|
##teamcity[testStarted name='it can pass with comparison' locationHint='pest_qn://tests/.tests/SuccessOnly.php::it can pass with comparison' flowId='1234']
|
||||||
##teamcity[testFinished name='it can pass with comparison' duration='100000' flowId='1234']
|
##teamcity[testFinished name='it can pass with comparison' duration='100000' flowId='1234']
|
||||||
##teamcity[testStarted name='can also pass' locationHint='pest_qn://tests/.tests/SuccessOnly.php::can also pass' flowId='1234']
|
##teamcity[testStarted name='can also pass' locationHint='pest_qn://tests/.tests/SuccessOnly.php::can also pass' flowId='1234']
|
||||||
|
|||||||
@ -8,4 +8,10 @@
|
|||||||
PASS Tests\Fixtures\ExampleTest
|
PASS Tests\Fixtures\ExampleTest
|
||||||
✓ it example 2
|
✓ it example 2
|
||||||
|
|
||||||
Tests: 2 skipped, 2 passed (2 assertions)
|
WARN Tests\Fixtures\Inheritance\Base\ExampleTest
|
||||||
|
- example
|
||||||
|
|
||||||
|
PASS Tests\Fixtures\Inheritance\ExampleTest
|
||||||
|
✓ example
|
||||||
|
|
||||||
|
Tests: 3 skipped, 3 passed (3 assertions)
|
||||||
|
|||||||
@ -1,7 +1,7 @@
|
|||||||
|
|
||||||
⨯.
|
.⨯.
|
||||||
────────────────────────────────────────────────────────────────────────────
|
────────────────────────────────────────────────────────────────────────────
|
||||||
FAILED Tests\Fixtures\CollisionTest > success Exception
|
FAILED Tests\Fixtures\CollisionTest > error Exception
|
||||||
error
|
error
|
||||||
|
|
||||||
at tests/Fixtures/CollisionTest.php:4
|
at tests/Fixtures/CollisionTest.php:4
|
||||||
@ -19,4 +19,4 @@
|
|||||||
2 src/Factories/TestCaseMethodFactory.php:100
|
2 src/Factories/TestCaseMethodFactory.php:100
|
||||||
|
|
||||||
|
|
||||||
Tests: 1 failed, 1 passed (1 assertions)
|
Tests: 1 failed, 2 passed (2 assertions)
|
||||||
@ -1,5 +1,5 @@
|
|||||||
|
|
||||||
Pest Testing Framework 2.2.0.
|
Pest Testing Framework 2.4.0.
|
||||||
|
|
||||||
USAGE: pest <file> [options]
|
USAGE: pest <file> [options]
|
||||||
|
|
||||||
@ -43,17 +43,17 @@
|
|||||||
--enforce-time-limit ................. Enforce time limit based on test size
|
--enforce-time-limit ................. Enforce time limit based on test size
|
||||||
--default-time-limit [sec] Timeout in seconds for tests that have no declared size
|
--default-time-limit [sec] Timeout in seconds for tests that have no declared size
|
||||||
--dont-report-useless-tests .. Do not report tests that do not test anything
|
--dont-report-useless-tests .. Do not report tests that do not test anything
|
||||||
--stop-on-defect ................. Stop execution upon first not-passed test
|
--stop-on-defect ... Stop after first error, failure, warning or, risky test
|
||||||
--stop-on-error ............................ Stop execution upon first error
|
--stop-on-error ..................................... Stop after first error
|
||||||
--stop-on-failure ............... Stop execution upon first error or failure
|
--stop-on-failure ................................. Stop after first failure
|
||||||
--stop-on-warning ........................ Stop execution upon first warning
|
--stop-on-warning ................................. Stop after first warning
|
||||||
--stop-on-risky ....................... Stop execution upon first risky test
|
--stop-on-risky ................................ Stop after first risky test
|
||||||
--stop-on-skipped ................... Stop execution upon first skipped test
|
--stop-on-skipped ............................ Stop after first skipped test
|
||||||
--stop-on-incomplete ............. Stop execution upon first incomplete test
|
--stop-on-incomplete ...................... Stop after first incomplete test
|
||||||
--fail-on-incomplete .................... Treat incomplete tests as failures
|
--fail-on-warning Signal failure using shell exit code when a warning was triggered
|
||||||
--fail-on-risky .............................. Treat risky tests as failures
|
--fail-on-risky Signal failure using shell exit code when a test was considered risky
|
||||||
--fail-on-skipped .......................... Treat skipped tests as failures
|
--fail-on-skipped Signal failure using shell exit code when a test was skipped
|
||||||
--fail-on-warning .................... Treat tests with warnings as failures
|
--fail-on-incomplete Signal failure using shell exit code when a test was marked incomplete
|
||||||
--cache-result ............................ Write test results to cache file
|
--cache-result ............................ Write test results to cache file
|
||||||
--do-not-cache-result .............. Do not write test results to cache file
|
--do-not-cache-result .............. Do not write test results to cache file
|
||||||
--order-by [order] Run tests in order: default|defects|depends|duration|no-depends|random|reverse|size
|
--order-by [order] Run tests in order: default|defects|depends|duration|no-depends|random|reverse|size
|
||||||
|
|||||||
@ -60,8 +60,8 @@
|
|||||||
✓ eager wrapped registered datasets with (1)
|
✓ eager wrapped registered datasets with (1)
|
||||||
✓ eager wrapped registered datasets with (2)
|
✓ eager wrapped registered datasets with (2)
|
||||||
✓ eager registered wrapped datasets did the job right
|
✓ eager registered wrapped datasets did the job right
|
||||||
✓ named datasets with data set "one"
|
✓ named datasets with dataset "one"
|
||||||
✓ named datasets with data set "two"
|
✓ named datasets with dataset "two"
|
||||||
✓ named datasets did the job right
|
✓ named datasets did the job right
|
||||||
✓ lazy named datasets with (Bar Object (…))
|
✓ lazy named datasets with (Bar Object (…))
|
||||||
✓ it creates unique test case names with ('Name 1', Pest\Plugin Object (), true) #1
|
✓ it creates unique test case names with ('Name 1', Pest\Plugin Object (), true) #1
|
||||||
@ -96,10 +96,10 @@
|
|||||||
✓ eager wrapped registered multiple datasets with (2) / (1)
|
✓ eager wrapped registered multiple datasets with (2) / (1)
|
||||||
✓ eager wrapped registered multiple datasets with (2) / (2)
|
✓ eager wrapped registered multiple datasets with (2) / (2)
|
||||||
✓ eager wrapped registered multiple datasets did the job right
|
✓ eager wrapped registered multiple datasets did the job right
|
||||||
✓ named multiple datasets with data set "one" / data set "three"
|
✓ named multiple datasets with dataset "one" / dataset "three"
|
||||||
✓ named multiple datasets with data set "one" / data set "four"
|
✓ named multiple datasets with dataset "one" / dataset "four"
|
||||||
✓ named multiple datasets with data set "two" / data set "three"
|
✓ named multiple datasets with dataset "two" / dataset "three"
|
||||||
✓ named multiple datasets with data set "two" / data set "four"
|
✓ named multiple datasets with dataset "two" / dataset "four"
|
||||||
✓ named multiple datasets did the job right
|
✓ named multiple datasets did the job right
|
||||||
✓ more than two datasets with (1) / (3) / (5)
|
✓ more than two datasets with (1) / (3) / (5)
|
||||||
✓ more than two datasets with (1) / (3) / (6)
|
✓ more than two datasets with (1) / (3) / (6)
|
||||||
@ -115,8 +115,8 @@
|
|||||||
✓ eager registered wrapped datasets with Generator functions with (3)
|
✓ eager registered wrapped datasets with Generator functions with (3)
|
||||||
✓ eager registered wrapped datasets with Generator functions with (4)
|
✓ eager registered wrapped datasets with Generator functions with (4)
|
||||||
✓ eager registered wrapped datasets with Generator functions did the job right
|
✓ eager registered wrapped datasets with Generator functions did the job right
|
||||||
✓ eager registered wrapped datasets with Generator functions display description with data set "taylor"
|
✓ eager registered wrapped datasets with Generator functions display description with dataset "taylor"
|
||||||
✓ eager registered wrapped datasets with Generator functions display description with data set "james"
|
✓ eager registered wrapped datasets with Generator functions display description with dataset "james"
|
||||||
✓ it can resolve a dataset after the test case is available with (Closure Object (…)) #1
|
✓ it can resolve a dataset after the test case is available with (Closure Object (…)) #1
|
||||||
✓ it can resolve a dataset after the test case is available with (Closure Object (…)) #2
|
✓ it can resolve a dataset after the test case is available with (Closure Object (…)) #2
|
||||||
✓ it can resolve a dataset after the test case is available with multiple datasets with (Closure Object (…)) / (Closure Object (…)) #1
|
✓ it can resolve a dataset after the test case is available with multiple datasets with (Closure Object (…)) / (Closure Object (…)) #1
|
||||||
@ -673,6 +673,7 @@
|
|||||||
✓ it throws error if method do not exist
|
✓ it throws error if method do not exist
|
||||||
✓ it can forward unexpected calls to any global function
|
✓ it can forward unexpected calls to any global function
|
||||||
✓ it can use helpers from helpers file
|
✓ it can use helpers from helpers file
|
||||||
|
✓ it can use helpers from helpers directory
|
||||||
|
|
||||||
PASS Tests\Features\HigherOrderTests
|
PASS Tests\Features\HigherOrderTests
|
||||||
✓ it proxies calls to object
|
✓ it proxies calls to object
|
||||||
@ -789,6 +790,9 @@
|
|||||||
PASS Tests\Fixtures\ExampleTest
|
PASS Tests\Fixtures\ExampleTest
|
||||||
✓ it example 2
|
✓ it example 2
|
||||||
|
|
||||||
|
PASS Tests\Helpers\TestInHelpers
|
||||||
|
✓ it executes tests in the Helpers directory
|
||||||
|
|
||||||
PASS Tests\Hooks\AfterAllTest
|
PASS Tests\Hooks\AfterAllTest
|
||||||
✓ global afterAll execution order
|
✓ global afterAll execution order
|
||||||
✓ it only gets called once per file
|
✓ it only gets called once per file
|
||||||
@ -864,6 +868,9 @@
|
|||||||
✓ it throw expectation failed exception with string argument
|
✓ it throw expectation failed exception with string argument
|
||||||
✓ it throw expectation failed exception with array argument
|
✓ it throw expectation failed exception with array argument
|
||||||
|
|
||||||
|
PASS Tests\Unit\Overrides\ThrowableBuilder
|
||||||
|
✓ collision editor can be added to the stack trace
|
||||||
|
|
||||||
PASS Tests\Unit\Plugins\Environment
|
PASS Tests\Unit\Plugins\Environment
|
||||||
✓ environment is set to CI when --ci option is used
|
✓ environment is set to CI when --ci option is used
|
||||||
✓ environment is set to Local when --ci option is not used
|
✓ environment is set to Local when --ci option is not used
|
||||||
@ -903,13 +910,17 @@
|
|||||||
✓ it computes the dataset scope with ('/var/www/project/tests/Featur…rs.php', '/var/www/project/tests/Featur…rs.php') #2
|
✓ it computes the dataset scope with ('/var/www/project/tests/Featur…rs.php', '/var/www/project/tests/Featur…rs.php') #2
|
||||||
✓ it computes the dataset scope with ('/var/www/project/tests/Featur…ts.php', '/var/www/project/tests/Featur…ollers')
|
✓ it computes the dataset scope with ('/var/www/project/tests/Featur…ts.php', '/var/www/project/tests/Featur…ollers')
|
||||||
|
|
||||||
|
PASS Tests\Unit\Support\ExceptionTrace
|
||||||
|
✓ it ensures the given closures reports the correct class name
|
||||||
|
✓ it ensures the given closures reports the correct class name and suggests the [uses()] function
|
||||||
|
|
||||||
PASS Tests\Unit\Support\Reflection
|
PASS Tests\Unit\Support\Reflection
|
||||||
✓ it gets file name from closure
|
✓ it gets file name from closure
|
||||||
✓ it gets property values
|
✓ it gets property values
|
||||||
|
|
||||||
PASS Tests\Unit\Support\Str
|
PASS Tests\Unit\Support\Str
|
||||||
✓ it evaluates the code with ('version()', '__pest_evaluable_version__')
|
✓ it evaluates the code with ('version()', '__pest_evaluable_version__')
|
||||||
✓ it evaluates the code with ('version__ ', '__pest_evaluable_version___')
|
✓ it evaluates the code with ('version__ ', '__pest_evaluable_version_____')
|
||||||
✓ it evaluates the code with ('version\', '__pest_evaluable_version_')
|
✓ it evaluates the code with ('version\', '__pest_evaluable_version_')
|
||||||
|
|
||||||
PASS Tests\Unit\TestName
|
PASS Tests\Unit\TestName
|
||||||
@ -918,6 +929,8 @@
|
|||||||
✓ it may start with P with ('P\PPPackages\Foo', 'PPPackages\Foo')
|
✓ it may start with P with ('P\PPPackages\Foo', 'PPPackages\Foo')
|
||||||
✓ it may start with P with ('PPPackages\Foo', 'PPPackages\Foo') #1
|
✓ it may start with P with ('PPPackages\Foo', 'PPPackages\Foo') #1
|
||||||
✓ it may start with P with ('PPPackages\Foo', 'PPPackages\Foo') #2
|
✓ it may start with P with ('PPPackages\Foo', 'PPPackages\Foo') #2
|
||||||
|
✓ test description
|
||||||
|
✓ test_description
|
||||||
✓ ふ+が+
|
✓ ふ+が+
|
||||||
✓ ほげ
|
✓ ほげ
|
||||||
✓ 卜竹弓一十山
|
✓ 卜竹弓一十山
|
||||||
@ -982,6 +995,7 @@
|
|||||||
|
|
||||||
PASS Tests\Visual\Parallel
|
PASS Tests\Visual\Parallel
|
||||||
✓ parallel
|
✓ parallel
|
||||||
|
✓ a parallel test can extend another test with same name
|
||||||
|
|
||||||
PASS Tests\Visual\SingleTestOrDirectory
|
PASS Tests\Visual\SingleTestOrDirectory
|
||||||
✓ allows to run a single test
|
✓ allows to run a single test
|
||||||
@ -1002,4 +1016,4 @@
|
|||||||
PASS Tests\Visual\Version
|
PASS Tests\Visual\Version
|
||||||
✓ visual snapshot of help command output
|
✓ visual snapshot of help command output
|
||||||
|
|
||||||
Tests: 2 deprecated, 3 warnings, 4 incomplete, 1 notice, 4 todos, 14 skipped, 701 passed (1698 assertions)
|
Tests: 2 deprecated, 3 warnings, 4 incomplete, 1 notice, 4 todos, 14 skipped, 709 passed (1717 assertions)
|
||||||
@ -1,3 +1,3 @@
|
|||||||
|
|
||||||
Pest Testing Framework 2.2.0.
|
Pest Testing Framework 2.4.0.
|
||||||
|
|
||||||
|
|||||||
@ -4,30 +4,49 @@ use PHPUnit\Framework\ExpectationFailedException;
|
|||||||
|
|
||||||
test('pass', function () {
|
test('pass', function () {
|
||||||
$object = new stdClass();
|
$object = new stdClass();
|
||||||
$object->name = 'Jhon';
|
$object->name = 'John';
|
||||||
$object->age = 21;
|
$object->age = 21;
|
||||||
|
|
||||||
expect($object)->toHaveProperties(['name', 'age']);
|
expect($object)
|
||||||
|
->toHaveProperties(['name', 'age'])
|
||||||
|
->toHaveProperties([
|
||||||
|
'name' => 'John',
|
||||||
|
'age' => 21,
|
||||||
|
]);
|
||||||
});
|
});
|
||||||
|
|
||||||
test('failures', function () {
|
test('failures', function () {
|
||||||
$object = new stdClass();
|
$object = new stdClass();
|
||||||
$object->name = 'Jhon';
|
$object->name = 'John';
|
||||||
|
|
||||||
expect($object)->toHaveProperties(['name', 'age']);
|
expect($object)
|
||||||
|
->toHaveProperties(['name', 'age'])
|
||||||
|
->toHaveProperties([
|
||||||
|
'name' => 'John',
|
||||||
|
'age' => 21,
|
||||||
|
]);
|
||||||
})->throws(ExpectationFailedException::class);
|
})->throws(ExpectationFailedException::class);
|
||||||
|
|
||||||
test('failures with custom message', function () {
|
test('failures with custom message', function () {
|
||||||
$object = new stdClass();
|
$object = new stdClass();
|
||||||
$object->name = 'Jhon';
|
$object->name = 'John';
|
||||||
|
|
||||||
expect($object)->toHaveProperties(['name', 'age'], 'oh no!');
|
expect($object)
|
||||||
|
->toHaveProperties(['name', 'age'], 'oh no!')
|
||||||
|
->toHaveProperties([
|
||||||
|
'name' => 'John',
|
||||||
|
'age' => 21,
|
||||||
|
], 'oh no!');
|
||||||
})->throws(ExpectationFailedException::class, 'oh no!');
|
})->throws(ExpectationFailedException::class, 'oh no!');
|
||||||
|
|
||||||
test('not failures', function () {
|
test('not failures', function () {
|
||||||
$object = new stdClass();
|
$object = new stdClass();
|
||||||
$object->name = 'Jhon';
|
$object->name = 'John';
|
||||||
$object->age = 21;
|
$object->age = 21;
|
||||||
|
|
||||||
expect($object)->not->toHaveProperties(['name', 'age']);
|
expect($object)->not->toHaveProperties(['name', 'age'])
|
||||||
|
->not->toHaveProperties([
|
||||||
|
'name' => 'John',
|
||||||
|
'age' => 21,
|
||||||
|
]);
|
||||||
})->throws(ExpectationFailedException::class);
|
})->throws(ExpectationFailedException::class);
|
||||||
|
|||||||
@ -44,3 +44,5 @@ it('throws error if method do not exist', function () {
|
|||||||
it('can forward unexpected calls to any global function')->_assertThat();
|
it('can forward unexpected calls to any global function')->_assertThat();
|
||||||
|
|
||||||
it('can use helpers from helpers file')->myAssertTrue(true);
|
it('can use helpers from helpers file')->myAssertTrue(true);
|
||||||
|
|
||||||
|
it('can use helpers from helpers directory')->myDirectoryAssertTrue(true);
|
||||||
|
|||||||
13
tests/Fixtures/Inheritance/Base/ExampleTest.php
Normal file
13
tests/Fixtures/Inheritance/Base/ExampleTest.php
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Tests\Fixtures\Inheritance\Base;
|
||||||
|
|
||||||
|
use PHPUnit\Framework\TestCase;
|
||||||
|
|
||||||
|
class ExampleTest extends TestCase
|
||||||
|
{
|
||||||
|
public function testExample()
|
||||||
|
{
|
||||||
|
$this->markTestSkipped();
|
||||||
|
}
|
||||||
|
}
|
||||||
11
tests/Fixtures/Inheritance/ExampleTest.php
Normal file
11
tests/Fixtures/Inheritance/ExampleTest.php
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Tests\Fixtures\Inheritance;
|
||||||
|
|
||||||
|
class ExampleTest extends Base\ExampleTest
|
||||||
|
{
|
||||||
|
public function testExample()
|
||||||
|
{
|
||||||
|
$this->assertTrue(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
6
tests/Helpers/Helper.php
Normal file
6
tests/Helpers/Helper.php
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
function myDirectoryAssertTrue($value)
|
||||||
|
{
|
||||||
|
test()->assertTrue($value);
|
||||||
|
}
|
||||||
5
tests/Helpers/TestInHelpers.php
Normal file
5
tests/Helpers/TestInHelpers.php
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
it('executes tests in the Helpers directory', function () {
|
||||||
|
expect(true)->toBeTrue();
|
||||||
|
});
|
||||||
@ -10,8 +10,8 @@ it('show only the names of named datasets in their description', function () {
|
|||||||
],
|
],
|
||||||
], __FILE__));
|
], __FILE__));
|
||||||
|
|
||||||
expect($descriptions[0])->toBe('data set "one"')
|
expect($descriptions[0])->toBe('dataset "one"')
|
||||||
->and($descriptions[1])->toBe('data set "two"');
|
->and($descriptions[1])->toBe('dataset "two"');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('show the actual dataset of non-named datasets in their description', function () {
|
it('show the actual dataset of non-named datasets in their description', function () {
|
||||||
@ -38,10 +38,10 @@ it('show only the names of multiple named datasets in their description', functi
|
|||||||
],
|
],
|
||||||
], __FILE__));
|
], __FILE__));
|
||||||
|
|
||||||
expect($descriptions[0])->toBe('data set "one" / data set "three"');
|
expect($descriptions[0])->toBe('dataset "one" / dataset "three"');
|
||||||
expect($descriptions[1])->toBe('data set "one" / data set "four"');
|
expect($descriptions[1])->toBe('dataset "one" / dataset "four"');
|
||||||
expect($descriptions[2])->toBe('data set "two" / data set "three"');
|
expect($descriptions[2])->toBe('dataset "two" / dataset "three"');
|
||||||
expect($descriptions[3])->toBe('data set "two" / data set "four"');
|
expect($descriptions[3])->toBe('dataset "two" / dataset "four"');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('show the actual dataset of multiple non-named datasets in their description', function () {
|
it('show the actual dataset of multiple non-named datasets in their description', function () {
|
||||||
@ -74,10 +74,10 @@ it('show the correct description for mixed named and not-named datasets', functi
|
|||||||
],
|
],
|
||||||
], __FILE__));
|
], __FILE__));
|
||||||
|
|
||||||
expect($descriptions[0])->toBe('data set "one" / (3)');
|
expect($descriptions[0])->toBe('dataset "one" / (3)');
|
||||||
expect($descriptions[1])->toBe('data set "one" / data set "four"');
|
expect($descriptions[1])->toBe('dataset "one" / dataset "four"');
|
||||||
expect($descriptions[2])->toBe('([2]) / (3)');
|
expect($descriptions[2])->toBe('([2]) / (3)');
|
||||||
expect($descriptions[3])->toBe('([2]) / data set "four"');
|
expect($descriptions[3])->toBe('([2]) / dataset "four"');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('shows the correct description for long texts with newlines', function () {
|
it('shows the correct description for long texts with newlines', function () {
|
||||||
|
|||||||
28
tests/Unit/Overrides/ThrowableBuilder.php
Normal file
28
tests/Unit/Overrides/ThrowableBuilder.php
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
use NunoMaduro\Collision\Contracts\RenderableOnCollisionEditor;
|
||||||
|
use PHPUnit\Event\Code\ThrowableBuilder;
|
||||||
|
use Whoops\Exception\Frame;
|
||||||
|
|
||||||
|
test('collision editor can be added to the stack trace', function () {
|
||||||
|
$exception = new class extends Exception implements RenderableOnCollisionEditor
|
||||||
|
{
|
||||||
|
public function __construct()
|
||||||
|
{
|
||||||
|
parent::__construct('test exception');
|
||||||
|
}
|
||||||
|
|
||||||
|
public function toCollisionEditor(): Frame
|
||||||
|
{
|
||||||
|
return new Frame([
|
||||||
|
'file' => __DIR__.'/../../Pest.php',
|
||||||
|
'line' => 5,
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
expect(str_replace(DIRECTORY_SEPARATOR, '/', ThrowableBuilder::from($exception)->stackTrace()))
|
||||||
|
->toContain('tests/Unit/Overrides/../../Pest.php:5')
|
||||||
|
->and(str_replace(DIRECTORY_SEPARATOR, '/', ThrowableBuilder::from(new Exception('test'))->stackTrace()))
|
||||||
|
->toContain('tests/Unit/Overrides/ThrowableBuilder.php:26');
|
||||||
|
});
|
||||||
21
tests/Unit/Support/ExceptionTrace.php
Normal file
21
tests/Unit/Support/ExceptionTrace.php
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
use Pest\Support\ExceptionTrace;
|
||||||
|
|
||||||
|
it('ensures the given closures reports the correct class name', function () {
|
||||||
|
$closure = function () {
|
||||||
|
throw new Exception('Call to undefined method P\Tests\IntentionallyNotExisting::testBasic().');
|
||||||
|
};
|
||||||
|
|
||||||
|
ExceptionTrace::ensure($closure);
|
||||||
|
})->throws(
|
||||||
|
Exception::class,
|
||||||
|
'Call to undefined method Tests\IntentionallyNotExisting::testBasic().',
|
||||||
|
);
|
||||||
|
|
||||||
|
it('ensures the given closures reports the correct class name and suggests the [uses()] function', function () {
|
||||||
|
$this->get();
|
||||||
|
})->throws(
|
||||||
|
Error::class,
|
||||||
|
'Call to undefined method Tests\Unit\Support\ExceptionTrace::get(). Did you forget to use the [uses()] function? Read more at: https://pestphp.com/docs/configuring-tests',
|
||||||
|
);
|
||||||
@ -8,6 +8,6 @@ it('evaluates the code', function ($evaluatable, $expected) {
|
|||||||
expect($code)->toBe($expected);
|
expect($code)->toBe($expected);
|
||||||
})->with([
|
})->with([
|
||||||
['version()', '__pest_evaluable_version__'],
|
['version()', '__pest_evaluable_version__'],
|
||||||
['version__ ', '__pest_evaluable_version___'],
|
['version__ ', '__pest_evaluable_version_____'],
|
||||||
['version\\', '__pest_evaluable_version_'],
|
['version\\', '__pest_evaluable_version_'],
|
||||||
]);
|
]);
|
||||||
|
|||||||
@ -13,6 +13,8 @@ it('may start with P', function (string $real, string $toBePrinted) {
|
|||||||
]);
|
]);
|
||||||
|
|
||||||
$names = [
|
$names = [
|
||||||
|
'test description' => '__pest_evaluable_test_description',
|
||||||
|
'test_description' => '__pest_evaluable_test__description',
|
||||||
'ふ+が+' => '__pest_evaluable_ふ_が_',
|
'ふ+が+' => '__pest_evaluable_ふ_が_',
|
||||||
'ほげ' => '__pest_evaluable_ほげ',
|
'ほげ' => '__pest_evaluable_ほげ',
|
||||||
'卜竹弓一十山' => '__pest_evaluable_卜竹弓一十山',
|
'卜竹弓一十山' => '__pest_evaluable_卜竹弓一十山',
|
||||||
|
|||||||
@ -39,4 +39,4 @@ test('collision', function (array $arguments) {
|
|||||||
})->with([
|
})->with([
|
||||||
[['']],
|
[['']],
|
||||||
[['--parallel']],
|
[['--parallel']],
|
||||||
])->skip(PHP_OS_FAMILY === 'Windows');
|
])->skipOnWindows();
|
||||||
|
|||||||
@ -18,4 +18,4 @@ test('visual snapshot of help command output', function () {
|
|||||||
}
|
}
|
||||||
|
|
||||||
expect($output())->toContain(file_get_contents($snapshot));
|
expect($output())->toContain(file_get_contents($snapshot));
|
||||||
})->skip(PHP_OS_FAMILY === 'Windows');
|
})->skipOnWindows();
|
||||||
|
|||||||
@ -3,7 +3,9 @@
|
|||||||
use Symfony\Component\Process\Process;
|
use Symfony\Component\Process\Process;
|
||||||
|
|
||||||
$run = function () {
|
$run = function () {
|
||||||
$process = new Process(['php', 'bin/pest', '--parallel', '--processes=3', '--exclude-group=integration'], dirname(__DIR__, 2),
|
$process = new Process(
|
||||||
|
array_merge(['php', 'bin/pest', '--parallel', '--processes=3'], func_get_args()),
|
||||||
|
dirname(__DIR__, 2),
|
||||||
['COLLISION_PRINTER' => 'DefaultPrinter', 'COLLISION_IGNORE_DURATION' => 'true'],
|
['COLLISION_PRINTER' => 'DefaultPrinter', 'COLLISION_IGNORE_DURATION' => 'true'],
|
||||||
);
|
);
|
||||||
|
|
||||||
@ -15,6 +17,11 @@ $run = function () {
|
|||||||
};
|
};
|
||||||
|
|
||||||
test('parallel', function () use ($run) {
|
test('parallel', function () use ($run) {
|
||||||
expect($run())->toContain('Tests: 2 deprecated, 3 warnings, 4 incomplete, 1 notice, 4 todos, 11 skipped, 690 passed (1684 assertions)')
|
expect($run('--exclude-group=integration'))
|
||||||
|
->toContain('Tests: 2 deprecated, 3 warnings, 4 incomplete, 1 notice, 4 todos, 11 skipped, 697 passed (1702 assertions)')
|
||||||
->toContain('Parallel: 3 processes');
|
->toContain('Parallel: 3 processes');
|
||||||
})->skip(PHP_OS_FAMILY === 'Windows');
|
})->skipOnWindows();
|
||||||
|
|
||||||
|
test('a parallel test can extend another test with same name', function () use ($run) {
|
||||||
|
expect($run('tests/Fixtures/Inheritance'))->toContain('Tests: 1 skipped, 2 passed (2 assertions)');
|
||||||
|
});
|
||||||
|
|||||||
@ -24,11 +24,11 @@ $snapshot = function ($name) {
|
|||||||
|
|
||||||
test('allows to run a single test', function () use ($run, $snapshot) {
|
test('allows to run a single test', function () use ($run, $snapshot) {
|
||||||
expect($run('tests/Fixtures/DirectoryWithTests/ExampleTest.php'))->toContain($snapshot('allows-to-run-a-single-test'));
|
expect($run('tests/Fixtures/DirectoryWithTests/ExampleTest.php'))->toContain($snapshot('allows-to-run-a-single-test'));
|
||||||
})->skip(PHP_OS_FAMILY === 'Windows');
|
})->skipOnWindows();
|
||||||
|
|
||||||
test('allows to run a directory', function () use ($run, $snapshot) {
|
test('allows to run a directory', function () use ($run, $snapshot) {
|
||||||
expect($run('tests/Fixtures'))->toContain($snapshot('allows-to-run-a-directory'));
|
expect($run('tests/Fixtures'))->toContain($snapshot('allows-to-run-a-directory'));
|
||||||
})->skip(PHP_OS_FAMILY === 'Windows');
|
})->skipOnWindows();
|
||||||
|
|
||||||
it('disable decorating printer when colors is set to never', function () use ($snapshot) {
|
it('disable decorating printer when colors is set to never', function () use ($snapshot) {
|
||||||
$process = new Process([
|
$process = new Process([
|
||||||
@ -40,4 +40,4 @@ it('disable decorating printer when colors is set to never', function () use ($s
|
|||||||
$process->run();
|
$process->run();
|
||||||
$output = $process->getOutput();
|
$output = $process->getOutput();
|
||||||
expect($output)->toContain($snapshot('disable-decorating-printer'));
|
expect($output)->toContain($snapshot('disable-decorating-printer'));
|
||||||
})->skip(PHP_OS_FAMILY === 'Windows');
|
})->skipOnWindows();
|
||||||
|
|||||||
@ -41,4 +41,4 @@ test('visual snapshot of test suite on success', function () {
|
|||||||
expect(implode("\n", $output))->toContain(file_get_contents($snapshot));
|
expect(implode("\n", $output))->toContain(file_get_contents($snapshot));
|
||||||
}
|
}
|
||||||
})->skip(! getenv('REBUILD_SNAPSHOTS') && getenv('EXCLUDE'))
|
})->skip(! getenv('REBUILD_SNAPSHOTS') && getenv('EXCLUDE'))
|
||||||
->skip(PHP_OS_FAMILY === 'Windows');
|
->skipOnWindows();
|
||||||
|
|||||||
@ -26,8 +26,8 @@ $snapshot = function ($name) {
|
|||||||
|
|
||||||
test('todo', function () use ($run, $snapshot) {
|
test('todo', function () use ($run, $snapshot) {
|
||||||
expect($run('--todos', false))->toContain($snapshot('todo'));
|
expect($run('--todos', false))->toContain($snapshot('todo'));
|
||||||
})->skip(PHP_OS_FAMILY === 'Windows');
|
})->skipOnWindows();
|
||||||
|
|
||||||
test('todo in parallel', function () use ($run, $snapshot) {
|
test('todo in parallel', function () use ($run, $snapshot) {
|
||||||
expect($run('--todos', true))->toContain($snapshot('todo'));
|
expect($run('--todos', true))->toContain($snapshot('todo'));
|
||||||
})->skip(PHP_OS_FAMILY === 'Windows');
|
})->skipOnWindows();
|
||||||
|
|||||||
@ -18,4 +18,4 @@ test('visual snapshot of help command output', function () {
|
|||||||
}
|
}
|
||||||
|
|
||||||
expect($output())->toContain(file_get_contents($snapshot));
|
expect($output())->toContain(file_get_contents($snapshot));
|
||||||
})->skip(PHP_OS_FAMILY === 'Windows');
|
})->skipOnWindows();
|
||||||
|
|||||||
Reference in New Issue
Block a user