mirror of
https://github.com/pestphp/pest.git
synced 2026-03-07 00:07:22 +01:00
Compare commits
43 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 7a699e16db | |||
| 341ba56bb9 | |||
| a320cc3e2b | |||
| 8b428357b2 | |||
| bb6d6b0951 | |||
| b94b8c6a4f | |||
| 43894afa18 | |||
| 28de31a8b9 | |||
| 974e70d7d1 | |||
| f914f1ad87 | |||
| 14dd5cb57b | |||
| 077ed287b7 | |||
| 9a41f2ff82 | |||
| 88f29e4180 | |||
| c34f649724 | |||
| e1e4f8d884 | |||
| 2d6d8b810b | |||
| bcd1503cad | |||
| e0f2919f62 | |||
| a8bd353ba6 | |||
| ed3bb2634d | |||
| 48ae4bfc18 | |||
| 26bb0b6eec | |||
| 236a9bd7ce | |||
| f4d19c90d3 | |||
| ecbaff503e | |||
| 9d0cd32e3f | |||
| 8782e9c34e | |||
| a4932e41de | |||
| 522ac55d5f | |||
| b3a8aef6ac | |||
| 8068bebebd | |||
| b887116e5c | |||
| 6071d86ac6 | |||
| 5723da1043 | |||
| 17e242a5f6 | |||
| c9a8007811 | |||
| c64c41a4d9 | |||
| da4bf7f5c3 | |||
| bb5dbc878e | |||
| 7d89d3546e | |||
| 1f3e5115c7 | |||
| 9de85175db |
25
CHANGELOG.md
25
CHANGELOG.md
@ -2,13 +2,34 @@
|
|||||||
|
|
||||||
## Unreleased
|
## Unreleased
|
||||||
|
|
||||||
|
## [v2.2.0 (2023-03-22)](https://github.com/pestphp/pest/compare/v2.1.0...v2.2.0)
|
||||||
|
|
||||||
|
### Added
|
||||||
|
- Improved error messages on dataset arguments mismatch ([#698](https://github.com/pestphp/pest/pull/698))
|
||||||
|
- Allows the usage of `DateTimeInterface` on multiple expectations ([#716](https://github.com/pestphp/pest/pull/716))
|
||||||
|
|
||||||
|
### Fixed
|
||||||
|
- `--dirty` option on Windows environments ([#721](https://github.com/pestphp/pest/pull/721))
|
||||||
|
- Parallel exit code when `phpunit.xml` is outdated ([14dd5cb](https://github.com/pestphp/pest/commit/14dd5cb57b9432300ac4e8095f069941cb43bdb5))
|
||||||
|
|
||||||
|
## [v2.1.0 (2023-03-21)](https://github.com/pestphp/pest/compare/v2.0.2...v2.1.0)
|
||||||
|
|
||||||
|
### Added
|
||||||
|
- `only` test case method ([bcd1503](https://github.com/pestphp/pest/commit/bcd1503cade938853a55c1283b02b6b820ea0b69))
|
||||||
|
|
||||||
|
### Fixed
|
||||||
|
- Issues with different characters on test names ([715](https://github.com/pestphp/pest/pull/715))
|
||||||
|
|
||||||
|
## [v2.0.2 (2023-03-20)](https://github.com/pestphp/pest/compare/v2.0.1...v2.0.2)
|
||||||
|
|
||||||
|
### Fixed
|
||||||
|
- `Pest.php` not being loaded in certain scenarios ([b887116](https://github.com/pestphp/pest/commit/b887116e5ce9a69403ad620cad20f0a029474eb5))
|
||||||
|
|
||||||
## [v2.0.1 (2023-03-20)](https://github.com/pestphp/pest/compare/v2.0.0...v2.0.1)
|
## [v2.0.1 (2023-03-20)](https://github.com/pestphp/pest/compare/v2.0.0...v2.0.1)
|
||||||
|
|
||||||
### Fixed
|
### Fixed
|
||||||
- Wrong `version` configuration key on `composer.json` ([8f91f40](https://github.com/pestphp/pest/commit/8f91f40e8ea8b35e04b7989bed6a8f9439e2a2d6))
|
- Wrong `version` configuration key on `composer.json` ([8f91f40](https://github.com/pestphp/pest/commit/8f91f40e8ea8b35e04b7989bed6a8f9439e2a2d6))
|
||||||
|
|
||||||
###
|
|
||||||
|
|
||||||
## [v2.0.0 (2023-03-20)](https://github.com/pestphp/pest/compare/v1.22.6...v2.0.0)
|
## [v2.0.0 (2023-03-20)](https://github.com/pestphp/pest/compare/v1.22.6...v2.0.0)
|
||||||
|
|
||||||
Please consult the [upgrade guide](https://pestphp.com/docs/upgrade-guide) and [release notes](https://pestphp.com/docs/announcing-pest2) in the official Pest documentation.
|
Please consult the [upgrade guide](https://pestphp.com/docs/upgrade-guide) and [release notes](https://pestphp.com/docs/announcing-pest2) in the official Pest documentation.
|
||||||
|
|||||||
3
bin/pest
3
bin/pest
@ -1,7 +1,6 @@
|
|||||||
#!/usr/bin/env php
|
#!/usr/bin/env php
|
||||||
<?php declare(strict_types=1);
|
<?php declare(strict_types=1);
|
||||||
|
|
||||||
use Pest\ConfigLoader;
|
|
||||||
use Pest\Kernel;
|
use Pest\Kernel;
|
||||||
use Pest\Panic;
|
use Pest\Panic;
|
||||||
use Pest\TestCaseFilters\GitDirtyTestCaseFilter;
|
use Pest\TestCaseFilters\GitDirtyTestCaseFilter;
|
||||||
@ -71,7 +70,7 @@ use Symfony\Component\Console\Output\ConsoleOutput;
|
|||||||
|
|
||||||
$testSuite = TestSuite::getInstance(
|
$testSuite = TestSuite::getInstance(
|
||||||
$rootPath,
|
$rootPath,
|
||||||
$input->getParameterOption('--test-directory', (new ConfigLoader($rootPath))->getTestsDirectory()),
|
$input->getParameterOption('--test-directory', 'tests'),
|
||||||
);
|
);
|
||||||
|
|
||||||
if ($dirty) {
|
if ($dirty) {
|
||||||
|
|||||||
@ -4,7 +4,6 @@ declare(strict_types=1);
|
|||||||
|
|
||||||
use ParaTest\WrapperRunner\ApplicationForWrapperWorker;
|
use ParaTest\WrapperRunner\ApplicationForWrapperWorker;
|
||||||
use ParaTest\WrapperRunner\WrapperWorker;
|
use ParaTest\WrapperRunner\WrapperWorker;
|
||||||
use Pest\ConfigLoader;
|
|
||||||
use Pest\Kernel;
|
use Pest\Kernel;
|
||||||
use Pest\Plugins\Actions\CallsHandleArguments;
|
use Pest\Plugins\Actions\CallsHandleArguments;
|
||||||
use Pest\TestSuite;
|
use Pest\TestSuite;
|
||||||
@ -18,7 +17,7 @@ $bootPest = (static function (): void {
|
|||||||
$rootPath = dirname(PHPUNIT_COMPOSER_INSTALL, 2);
|
$rootPath = dirname(PHPUNIT_COMPOSER_INSTALL, 2);
|
||||||
$testSuite = TestSuite::getInstance($rootPath, $workerArgv->getParameterOption(
|
$testSuite = TestSuite::getInstance($rootPath, $workerArgv->getParameterOption(
|
||||||
'--test-directory',
|
'--test-directory',
|
||||||
(new ConfigLoader($rootPath))->getTestsDirectory()
|
'tests'
|
||||||
));
|
));
|
||||||
|
|
||||||
$input = new ArgvInput();
|
$input = new ArgvInput();
|
||||||
|
|||||||
@ -18,16 +18,16 @@
|
|||||||
],
|
],
|
||||||
"require": {
|
"require": {
|
||||||
"php": "^8.1.0",
|
"php": "^8.1.0",
|
||||||
"brianium/paratest": "^7.1.1",
|
"brianium/paratest": "^7.1.2",
|
||||||
"nunomaduro/collision": "^7.2.0",
|
"nunomaduro/collision": "^7.3.2",
|
||||||
"nunomaduro/termwind": "^1.15.1",
|
"nunomaduro/termwind": "^1.15.1",
|
||||||
"pestphp/pest-plugin": "^2.0.0",
|
"pestphp/pest-plugin": "^2.0.0",
|
||||||
"pestphp/pest-plugin-arch": "^2.0.0",
|
"pestphp/pest-plugin-arch": "^2.0.1",
|
||||||
"phpunit/phpunit": "^10.0.16"
|
"phpunit/phpunit": "^10.0.17"
|
||||||
},
|
},
|
||||||
"conflict": {
|
"conflict": {
|
||||||
"webmozart/assert": "<1.11.0",
|
"webmozart/assert": "<1.11.0",
|
||||||
"phpunit/phpunit": ">10.0.16"
|
"phpunit/phpunit": ">10.0.17"
|
||||||
},
|
},
|
||||||
"autoload": {
|
"autoload": {
|
||||||
"psr-4": {
|
"psr-4": {
|
||||||
@ -71,7 +71,7 @@
|
|||||||
"test:unit": "php bin/pest --colors=always --exclude-group=integration --compact",
|
"test:unit": "php bin/pest --colors=always --exclude-group=integration --compact",
|
||||||
"test:inline": "php bin/pest --colors=always --configuration=phpunit.inline.xml",
|
"test:inline": "php bin/pest --colors=always --configuration=phpunit.inline.xml",
|
||||||
"test:parallel": "php bin/pest --colors=always --exclude-group=integration --parallel --processes=10",
|
"test:parallel": "php bin/pest --colors=always --exclude-group=integration --parallel --processes=10",
|
||||||
"test:integration": "php bin/pest --colors=always --group=integration -v",
|
"test:integration": "php bin/pest --colors=always --group=integration",
|
||||||
"update:snapshots": "REBUILD_SNAPSHOTS=true php bin/pest --colors=always",
|
"update:snapshots": "REBUILD_SNAPSHOTS=true php bin/pest --colors=always",
|
||||||
"test": [
|
"test": [
|
||||||
"@test:refacto",
|
"@test:refacto",
|
||||||
@ -92,6 +92,7 @@
|
|||||||
"Pest\\Plugins\\Environment",
|
"Pest\\Plugins\\Environment",
|
||||||
"Pest\\Plugins\\Help",
|
"Pest\\Plugins\\Help",
|
||||||
"Pest\\Plugins\\Memory",
|
"Pest\\Plugins\\Memory",
|
||||||
|
"Pest\\Plugins\\Only",
|
||||||
"Pest\\Plugins\\Printer",
|
"Pest\\Plugins\\Printer",
|
||||||
"Pest\\Plugins\\ProcessIsolation",
|
"Pest\\Plugins\\ProcessIsolation",
|
||||||
"Pest\\Plugins\\Profile",
|
"Pest\\Plugins\\Profile",
|
||||||
|
|||||||
128
overrides/TextUI/TestSuiteFilterProcessor.php
Normal file
128
overrides/TextUI/TestSuiteFilterProcessor.php
Normal file
@ -0,0 +1,128 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
/*
|
||||||
|
* BSD 3-Clause License
|
||||||
|
*
|
||||||
|
* Copyright (c) 2001-2023, Sebastian Bergmann
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are met:
|
||||||
|
*
|
||||||
|
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||||
|
* list of conditions and the following disclaimer.
|
||||||
|
*
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||||
|
* this list of conditions and the following disclaimer in the documentation
|
||||||
|
* and/or other materials provided with the distribution.
|
||||||
|
*
|
||||||
|
* 3. Neither the name of the copyright holder nor the names of its
|
||||||
|
* contributors may be used to endorse or promote products derived from
|
||||||
|
* this software without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||||
|
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||||
|
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
||||||
|
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||||
|
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||||
|
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||||
|
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||||
|
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
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\TextUI;
|
||||||
|
|
||||||
|
use function array_map;
|
||||||
|
use Pest\Plugins\Only;
|
||||||
|
use PHPUnit\Event;
|
||||||
|
use PHPUnit\Framework\TestSuite;
|
||||||
|
use PHPUnit\Runner\Filter\Factory;
|
||||||
|
use PHPUnit\TextUI\Configuration\Configuration;
|
||||||
|
use PHPUnit\TextUI\Configuration\FilterNotConfiguredException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @internal This class is not covered by the backward compatibility promise for PHPUnit
|
||||||
|
*/
|
||||||
|
final class TestSuiteFilterProcessor
|
||||||
|
{
|
||||||
|
private Factory $filterFactory;
|
||||||
|
|
||||||
|
public function __construct(Factory $factory = new Factory)
|
||||||
|
{
|
||||||
|
$this->filterFactory = $factory;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @throws Event\RuntimeException
|
||||||
|
* @throws FilterNotConfiguredException
|
||||||
|
*/
|
||||||
|
public function process(Configuration $configuration, TestSuite $suite): void
|
||||||
|
{
|
||||||
|
if (! $configuration->hasFilter() &&
|
||||||
|
! $configuration->hasGroups() &&
|
||||||
|
! $configuration->hasExcludeGroups() &&
|
||||||
|
! $configuration->hasTestsCovering() &&
|
||||||
|
! $configuration->hasTestsUsing() &&
|
||||||
|
! Only::isEnabled()
|
||||||
|
) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($configuration->hasExcludeGroups()) {
|
||||||
|
$this->filterFactory->addExcludeGroupFilter(
|
||||||
|
$configuration->excludeGroups()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Only::isEnabled()) {
|
||||||
|
$this->filterFactory->addIncludeGroupFilter(['__pest_only']);
|
||||||
|
} elseif ($configuration->hasGroups()) {
|
||||||
|
$this->filterFactory->addIncludeGroupFilter(
|
||||||
|
$configuration->groups()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($configuration->hasTestsCovering()) {
|
||||||
|
$this->filterFactory->addIncludeGroupFilter(
|
||||||
|
array_map(
|
||||||
|
static fn (string $name): string => '__phpunit_covers_'.$name,
|
||||||
|
$configuration->testsCovering()
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($configuration->hasTestsUsing()) {
|
||||||
|
$this->filterFactory->addIncludeGroupFilter(
|
||||||
|
array_map(
|
||||||
|
static fn (string $name): string => '__phpunit_uses_'.$name,
|
||||||
|
$configuration->testsUsing()
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($configuration->hasFilter()) {
|
||||||
|
$this->filterFactory->addNameFilter(
|
||||||
|
$configuration->filter()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
$suite->injectFilter($this->filterFactory);
|
||||||
|
|
||||||
|
Event\Facade::emitter()->testSuiteFiltered(
|
||||||
|
Event\TestSuite\TestSuiteBuilder::from($suite)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -23,6 +23,7 @@ final class BootOverrides implements Bootstrapper
|
|||||||
'Runner/TestSuiteLoader.php',
|
'Runner/TestSuiteLoader.php',
|
||||||
'TextUI/Command/WarmCodeCoverageCacheCommand.php',
|
'TextUI/Command/WarmCodeCoverageCacheCommand.php',
|
||||||
'TextUI/Output/Default/ProgressPrinter/TestSkippedSubscriber.php',
|
'TextUI/Output/Default/ProgressPrinter/TestSkippedSubscriber.php',
|
||||||
|
'TextUI/TestSuiteFilterProcessor.php',
|
||||||
];
|
];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@ -45,7 +45,7 @@ final class BootSubscribers implements Bootstrapper
|
|||||||
|
|
||||||
assert($instance instanceof Subscriber);
|
assert($instance instanceof Subscriber);
|
||||||
|
|
||||||
method_exists(Event\Facade::class, 'instance') ? Event\Facade::instance()->registerSubscriber($instance) : Event\Facade::registerSubscriber($instance); // @phpstan-ignore-line
|
Event\Facade::instance()->registerSubscriber($instance);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -5,11 +5,14 @@ declare(strict_types=1);
|
|||||||
namespace Pest\Concerns;
|
namespace Pest\Concerns;
|
||||||
|
|
||||||
use Closure;
|
use Closure;
|
||||||
|
use Pest\Exceptions\DatasetArgsCountMismatch;
|
||||||
use Pest\Support\ChainableClosure;
|
use Pest\Support\ChainableClosure;
|
||||||
use Pest\Support\ExceptionTrace;
|
use Pest\Support\ExceptionTrace;
|
||||||
use Pest\Support\Reflection;
|
use Pest\Support\Reflection;
|
||||||
use Pest\TestSuite;
|
use Pest\TestSuite;
|
||||||
use PHPUnit\Framework\TestCase;
|
use PHPUnit\Framework\TestCase;
|
||||||
|
use ReflectionException;
|
||||||
|
use ReflectionFunction;
|
||||||
use Throwable;
|
use Throwable;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -212,7 +215,10 @@ trait Testable
|
|||||||
*/
|
*/
|
||||||
private function __runTest(Closure $closure, ...$args): mixed
|
private function __runTest(Closure $closure, ...$args): mixed
|
||||||
{
|
{
|
||||||
return $this->__callClosure($closure, $this->__resolveTestArguments($args));
|
$arguments = $this->__resolveTestArguments($args);
|
||||||
|
$this->__ensureDatasetArgumentNumberMatches($arguments);
|
||||||
|
|
||||||
|
return $this->__callClosure($closure, $arguments);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -264,6 +270,30 @@ trait Testable
|
|||||||
return array_values($boundDatasetResult);
|
return array_values($boundDatasetResult);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Ensures dataset items count matches underlying test case required parameters
|
||||||
|
*
|
||||||
|
* @throws ReflectionException
|
||||||
|
* @throws DatasetArgsCountMismatch
|
||||||
|
*/
|
||||||
|
private function __ensureDatasetArgumentNumberMatches(array $arguments): void
|
||||||
|
{
|
||||||
|
if ($arguments === []) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
$underlyingTest = Reflection::getFunctionVariable($this->__test, 'closure');
|
||||||
|
$testReflection = new ReflectionFunction($underlyingTest);
|
||||||
|
$requiredParametersCount = $testReflection->getNumberOfRequiredParameters();
|
||||||
|
$suppliedParametersCount = count($arguments);
|
||||||
|
|
||||||
|
if ($suppliedParametersCount >= $requiredParametersCount) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
throw new DatasetArgsCountMismatch($this->dataName(), $requiredParametersCount, $suppliedParametersCount);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @throws Throwable
|
* @throws Throwable
|
||||||
*/
|
*/
|
||||||
|
|||||||
@ -1,113 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
declare(strict_types=1);
|
|
||||||
|
|
||||||
namespace Pest;
|
|
||||||
|
|
||||||
use Pest\Support\Str;
|
|
||||||
use SimpleXMLElement;
|
|
||||||
use Throwable;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @internal
|
|
||||||
*/
|
|
||||||
final class ConfigLoader
|
|
||||||
{
|
|
||||||
/**
|
|
||||||
* Default path if config loading went wrong.
|
|
||||||
*
|
|
||||||
* @var string
|
|
||||||
*/
|
|
||||||
public const DEFAULT_TESTS_PATH = 'tests';
|
|
||||||
|
|
||||||
/**
|
|
||||||
* XML tree of the PHPUnit configuration file.
|
|
||||||
*/
|
|
||||||
private ?SimpleXMLElement $config = null;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Creates a new instance of the config loader.
|
|
||||||
*/
|
|
||||||
public function __construct(private readonly string $rootPath)
|
|
||||||
{
|
|
||||||
$this->loadConfiguration();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the tests directory or fallback to default path.
|
|
||||||
*/
|
|
||||||
public function getTestsDirectory(): string
|
|
||||||
{
|
|
||||||
$suiteDirectory = [];
|
|
||||||
if (is_null($this->config)) {
|
|
||||||
return self::DEFAULT_TESTS_PATH;
|
|
||||||
}
|
|
||||||
|
|
||||||
$suiteDirectory = $this->config->xpath('/phpunit/testsuites/testsuite/directory');
|
|
||||||
|
|
||||||
if ($suiteDirectory === []) {
|
|
||||||
return self::DEFAULT_TESTS_PATH;
|
|
||||||
}
|
|
||||||
|
|
||||||
$directory = (string) ($suiteDirectory[0] ?? '');
|
|
||||||
|
|
||||||
if ($directory === '') {
|
|
||||||
return self::DEFAULT_TESTS_PATH;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Return the whole directory if only a separator found (e.g. `./tests`)
|
|
||||||
if (substr_count($directory, DIRECTORY_SEPARATOR) === 1) {
|
|
||||||
return is_dir($directory) ? $directory : self::DEFAULT_TESTS_PATH;
|
|
||||||
}
|
|
||||||
|
|
||||||
$basePath = Str::beforeLast($directory, DIRECTORY_SEPARATOR);
|
|
||||||
|
|
||||||
return is_dir($basePath) ? $basePath : self::DEFAULT_TESTS_PATH;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the configuration file path.
|
|
||||||
*/
|
|
||||||
public function getConfigurationFilePath(): string|bool
|
|
||||||
{
|
|
||||||
$candidates = [
|
|
||||||
$this->rootPath.'/phpunit.xml',
|
|
||||||
$this->rootPath.'/phpunit.dist.xml',
|
|
||||||
$this->rootPath.'/phpunit.xml.dist',
|
|
||||||
];
|
|
||||||
|
|
||||||
foreach ($candidates as $candidate) {
|
|
||||||
if (is_file($candidate)) {
|
|
||||||
return realpath($candidate);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Load the configuration file.
|
|
||||||
*/
|
|
||||||
private function loadConfiguration(): void
|
|
||||||
{
|
|
||||||
$configPath = $this->getConfigurationFilePath();
|
|
||||||
|
|
||||||
if (is_bool($configPath)) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
$oldReportingLevel = error_reporting(0);
|
|
||||||
$content = file_get_contents($configPath);
|
|
||||||
|
|
||||||
if ($content !== false) {
|
|
||||||
try {
|
|
||||||
$this->config = new SimpleXMLElement($content);
|
|
||||||
} catch (Throwable) { // @phpstan-ignore-line
|
|
||||||
// @ignoreException
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Restore the correct error reporting
|
|
||||||
error_reporting($oldReportingLevel);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
15
src/Exceptions/DatasetArgsCountMismatch.php
Normal file
15
src/Exceptions/DatasetArgsCountMismatch.php
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace Pest\Exceptions;
|
||||||
|
|
||||||
|
use Exception;
|
||||||
|
|
||||||
|
final class DatasetArgsCountMismatch extends Exception
|
||||||
|
{
|
||||||
|
public function __construct(string $dataName, int $requiredCount, int $suppliedCount)
|
||||||
|
{
|
||||||
|
parent::__construct(sprintf('Test expects %d arguments but dataset [%s] only provides %d', $requiredCount, $dataName, $suppliedCount));
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -64,7 +64,7 @@ final class Expectation
|
|||||||
*/
|
*/
|
||||||
public function and(mixed $value): Expectation
|
public function and(mixed $value): Expectation
|
||||||
{
|
{
|
||||||
return $value instanceof static ? $value : new self($value);
|
return $value instanceof self ? $value : new self($value);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@ -11,7 +11,9 @@ use Pest\Plugins\Actions\CallsBoot;
|
|||||||
use Pest\Plugins\Actions\CallsHandleArguments;
|
use Pest\Plugins\Actions\CallsHandleArguments;
|
||||||
use Pest\Plugins\Actions\CallsShutdown;
|
use Pest\Plugins\Actions\CallsShutdown;
|
||||||
use Pest\Support\Container;
|
use Pest\Support\Container;
|
||||||
|
use PHPUnit\TestRunner\TestResult\Facade;
|
||||||
use PHPUnit\TextUI\Application;
|
use PHPUnit\TextUI\Application;
|
||||||
|
use PHPUnit\TextUI\Configuration\Registry;
|
||||||
use Symfony\Component\Console\Input\InputInterface;
|
use Symfony\Component\Console\Input\InputInterface;
|
||||||
use Symfony\Component\Console\Output\OutputInterface;
|
use Symfony\Component\Console\Output\OutputInterface;
|
||||||
|
|
||||||
@ -90,8 +92,11 @@ final class Kernel
|
|||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$configuration = Registry::get();
|
||||||
|
$result = Facade::result();
|
||||||
|
|
||||||
return CallsAddsOutput::execute(
|
return CallsAddsOutput::execute(
|
||||||
Result::exitCode(),
|
Result::exitCode($configuration, $result),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -237,8 +237,7 @@ final class TeamCityLogger
|
|||||||
new TestExecutionFinishedSubscriber($this),
|
new TestExecutionFinishedSubscriber($this),
|
||||||
];
|
];
|
||||||
|
|
||||||
// @phpstan-ignore-next-line
|
Facade::instance()->registerSubscribers(...$subscribers);
|
||||||
method_exists(Facade::class, 'instance') ? Facade::instance()->registerSubscribers(...$subscribers) : Facade::registerSubscribers(...$subscribers);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private function setFlowId(): void
|
private function setFlowId(): void
|
||||||
|
|||||||
@ -6,6 +6,7 @@ namespace Pest\Mixins;
|
|||||||
|
|
||||||
use BadMethodCallException;
|
use BadMethodCallException;
|
||||||
use Closure;
|
use Closure;
|
||||||
|
use DateTimeInterface;
|
||||||
use Error;
|
use Error;
|
||||||
use InvalidArgumentException;
|
use InvalidArgumentException;
|
||||||
use Pest\Exceptions\InvalidExpectationValue;
|
use Pest\Exceptions\InvalidExpectationValue;
|
||||||
@ -124,7 +125,7 @@ final class Expectation
|
|||||||
*
|
*
|
||||||
* @return self<TValue>
|
* @return self<TValue>
|
||||||
*/
|
*/
|
||||||
public function toBeGreaterThan(int|float $expected, string $message = ''): self
|
public function toBeGreaterThan(int|float|DateTimeInterface $expected, string $message = ''): self
|
||||||
{
|
{
|
||||||
Assert::assertGreaterThan($expected, $this->value, $message);
|
Assert::assertGreaterThan($expected, $this->value, $message);
|
||||||
|
|
||||||
@ -136,7 +137,7 @@ final class Expectation
|
|||||||
*
|
*
|
||||||
* @return self<TValue>
|
* @return self<TValue>
|
||||||
*/
|
*/
|
||||||
public function toBeGreaterThanOrEqual(int|float $expected, string $message = ''): self
|
public function toBeGreaterThanOrEqual(int|float|DateTimeInterface $expected, string $message = ''): self
|
||||||
{
|
{
|
||||||
Assert::assertGreaterThanOrEqual($expected, $this->value, $message);
|
Assert::assertGreaterThanOrEqual($expected, $this->value, $message);
|
||||||
|
|
||||||
@ -148,7 +149,7 @@ final class Expectation
|
|||||||
*
|
*
|
||||||
* @return self<TValue>
|
* @return self<TValue>
|
||||||
*/
|
*/
|
||||||
public function toBeLessThan(int|float $expected, string $message = ''): self
|
public function toBeLessThan(int|float|DateTimeInterface $expected, string $message = ''): self
|
||||||
{
|
{
|
||||||
Assert::assertLessThan($expected, $this->value, $message);
|
Assert::assertLessThan($expected, $this->value, $message);
|
||||||
|
|
||||||
@ -160,7 +161,7 @@ final class Expectation
|
|||||||
*
|
*
|
||||||
* @return self<TValue>
|
* @return self<TValue>
|
||||||
*/
|
*/
|
||||||
public function toBeLessThanOrEqual(int|float $expected, string $message = ''): self
|
public function toBeLessThanOrEqual(int|float|DateTimeInterface $expected, string $message = ''): self
|
||||||
{
|
{
|
||||||
Assert::assertLessThanOrEqual($expected, $this->value, $message);
|
Assert::assertLessThanOrEqual($expected, $this->value, $message);
|
||||||
|
|
||||||
|
|||||||
@ -10,6 +10,7 @@ use Pest\Factories\Covers\CoversClass;
|
|||||||
use Pest\Factories\Covers\CoversFunction;
|
use Pest\Factories\Covers\CoversFunction;
|
||||||
use Pest\Factories\Covers\CoversNothing;
|
use Pest\Factories\Covers\CoversNothing;
|
||||||
use Pest\Factories\TestCaseMethodFactory;
|
use Pest\Factories\TestCaseMethodFactory;
|
||||||
|
use Pest\Plugins\Only;
|
||||||
use Pest\Support\Backtrace;
|
use Pest\Support\Backtrace;
|
||||||
use Pest\Support\Exporter;
|
use Pest\Support\Exporter;
|
||||||
use Pest\Support\HigherOrderCallables;
|
use Pest\Support\HigherOrderCallables;
|
||||||
@ -134,6 +135,16 @@ final class TestCall
|
|||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Filters the test suite by "only" tests.
|
||||||
|
*/
|
||||||
|
public function only(): self
|
||||||
|
{
|
||||||
|
Only::enable($this);
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Skips the current test.
|
* Skips the current test.
|
||||||
*/
|
*/
|
||||||
|
|||||||
@ -6,7 +6,7 @@ namespace Pest;
|
|||||||
|
|
||||||
function version(): string
|
function version(): string
|
||||||
{
|
{
|
||||||
return '2.0.1';
|
return '2.2.0';
|
||||||
}
|
}
|
||||||
|
|
||||||
function testDirectory(string $file = ''): string
|
function testDirectory(string $file = ''): string
|
||||||
|
|||||||
@ -102,6 +102,13 @@ final class Help implements HandlesArguments
|
|||||||
'desc' => 'Initialise a standard Pest configuration',
|
'desc' => 'Initialise a standard Pest configuration',
|
||||||
]], ...$content['Configuration']];
|
]], ...$content['Configuration']];
|
||||||
|
|
||||||
|
$content['Execution'] = [...[
|
||||||
|
[
|
||||||
|
'arg' => '--parallel',
|
||||||
|
'desc' => 'Run tests in parallel',
|
||||||
|
],
|
||||||
|
], ...$content['Execution']];
|
||||||
|
|
||||||
$content['Selection'] = array_merge([
|
$content['Selection'] = array_merge([
|
||||||
[
|
[
|
||||||
'arg' => '--bail',
|
'arg' => '--bail',
|
||||||
|
|||||||
61
src/Plugins/Only.php
Normal file
61
src/Plugins/Only.php
Normal file
@ -0,0 +1,61 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace Pest\Plugins;
|
||||||
|
|
||||||
|
use Pest\Contracts\Plugins\Shutdownable;
|
||||||
|
use Pest\PendingCalls\TestCall;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @internal
|
||||||
|
*/
|
||||||
|
final class Only implements Shutdownable
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* The temporary folder.
|
||||||
|
*/
|
||||||
|
private const TEMPORARY_FOLDER = __DIR__
|
||||||
|
.DIRECTORY_SEPARATOR
|
||||||
|
.'..'
|
||||||
|
.DIRECTORY_SEPARATOR
|
||||||
|
.'..'
|
||||||
|
.DIRECTORY_SEPARATOR
|
||||||
|
.'.temp';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritDoc}
|
||||||
|
*/
|
||||||
|
public function shutdown(): void
|
||||||
|
{
|
||||||
|
$lockFile = self::TEMPORARY_FOLDER.DIRECTORY_SEPARATOR.'only.lock';
|
||||||
|
|
||||||
|
if (file_exists($lockFile)) {
|
||||||
|
unlink($lockFile);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates the lock file.
|
||||||
|
*/
|
||||||
|
public static function enable(TestCall $testCall): void
|
||||||
|
{
|
||||||
|
$testCall->group('__pest_only');
|
||||||
|
|
||||||
|
$lockFile = self::TEMPORARY_FOLDER.DIRECTORY_SEPARATOR.'only.lock';
|
||||||
|
|
||||||
|
if (! file_exists($lockFile)) {
|
||||||
|
touch($lockFile);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks if "only" mode is enabled.
|
||||||
|
*/
|
||||||
|
public static function isEnabled(): bool
|
||||||
|
{
|
||||||
|
$lockFile = self::TEMPORARY_FOLDER.DIRECTORY_SEPARATOR.'only.lock';
|
||||||
|
|
||||||
|
return file_exists($lockFile);
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -20,13 +20,13 @@ use ParaTest\Options;
|
|||||||
use ParaTest\RunnerInterface;
|
use ParaTest\RunnerInterface;
|
||||||
use ParaTest\WrapperRunner\SuiteLoader;
|
use ParaTest\WrapperRunner\SuiteLoader;
|
||||||
use ParaTest\WrapperRunner\WrapperWorker;
|
use ParaTest\WrapperRunner\WrapperWorker;
|
||||||
|
use Pest\Result;
|
||||||
use Pest\TestSuite;
|
use Pest\TestSuite;
|
||||||
use PHPUnit\Event\Facade as EventFacade;
|
use PHPUnit\Event\Facade as EventFacade;
|
||||||
use PHPUnit\Runner\CodeCoverage;
|
use PHPUnit\Runner\CodeCoverage;
|
||||||
use PHPUnit\TestRunner\TestResult\Facade as TestResultFacade;
|
use PHPUnit\TestRunner\TestResult\Facade as TestResultFacade;
|
||||||
use PHPUnit\TestRunner\TestResult\TestResult;
|
use PHPUnit\TestRunner\TestResult\TestResult;
|
||||||
use PHPUnit\TextUI\Configuration\CodeCoverageFilterRegistry;
|
use PHPUnit\TextUI\Configuration\CodeCoverageFilterRegistry;
|
||||||
use PHPUnit\TextUI\ShellExitCodeCalculator;
|
|
||||||
use PHPUnit\Util\ExcludeList;
|
use PHPUnit\Util\ExcludeList;
|
||||||
use function realpath;
|
use function realpath;
|
||||||
use SebastianBergmann\Timer\Timer;
|
use SebastianBergmann\Timer\Timer;
|
||||||
@ -115,8 +115,7 @@ final class WrapperRunner implements RunnerInterface
|
|||||||
|
|
||||||
TestResultFacade::init();
|
TestResultFacade::init();
|
||||||
|
|
||||||
// @phpstan-ignore-next-line
|
EventFacade::instance()->seal();
|
||||||
method_exists(EventFacade::class, 'instance') ? EventFacade::instance()->seal() : EventFacade::seal();
|
|
||||||
|
|
||||||
$suiteLoader = new SuiteLoader($this->options, $this->output, $this->codeCoverageFilterRegistry);
|
$suiteLoader = new SuiteLoader($this->options, $this->output, $this->codeCoverageFilterRegistry);
|
||||||
$this->pending = $this->getTestFiles($suiteLoader);
|
$this->pending = $this->getTestFiles($suiteLoader);
|
||||||
@ -331,14 +330,7 @@ final class WrapperRunner implements RunnerInterface
|
|||||||
$this->generateCodeCoverageReports();
|
$this->generateCodeCoverageReports();
|
||||||
$this->generateLogs();
|
$this->generateLogs();
|
||||||
|
|
||||||
$exitCode = (new ShellExitCodeCalculator())->calculate(
|
$exitCode = Result::exitCode($this->options->configuration, $testResultSum);
|
||||||
$this->options->configuration->failOnEmptyTestSuite(),
|
|
||||||
$this->options->configuration->failOnRisky(),
|
|
||||||
$this->options->configuration->failOnWarning(),
|
|
||||||
$this->options->configuration->failOnIncomplete(),
|
|
||||||
$this->options->configuration->failOnSkipped(),
|
|
||||||
$testResultSum,
|
|
||||||
);
|
|
||||||
|
|
||||||
$this->clearFiles($this->testresultFiles);
|
$this->clearFiles($this->testresultFiles);
|
||||||
$this->clearFiles($this->coverageFiles);
|
$this->clearFiles($this->coverageFiles);
|
||||||
|
|||||||
@ -4,8 +4,8 @@ declare(strict_types=1);
|
|||||||
|
|
||||||
namespace Pest;
|
namespace Pest;
|
||||||
|
|
||||||
use PHPUnit\TestRunner\TestResult\Facade;
|
use PHPUnit\TestRunner\TestResult\TestResult;
|
||||||
use PHPUnit\TextUI\Configuration\Registry;
|
use PHPUnit\TextUI\Configuration\Configuration;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @internal
|
* @internal
|
||||||
@ -21,26 +21,24 @@ final class Result
|
|||||||
/**
|
/**
|
||||||
* If the exit code is different from 0.
|
* If the exit code is different from 0.
|
||||||
*/
|
*/
|
||||||
public static function failed(): bool
|
public static function failed(Configuration $configuration, TestResult $result): bool
|
||||||
{
|
{
|
||||||
return ! self::ok();
|
return ! self::ok($configuration, $result);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* If the exit code is exactly 0.
|
* If the exit code is exactly 0.
|
||||||
*/
|
*/
|
||||||
public static function ok(): bool
|
public static function ok(Configuration $configuration, TestResult $result): bool
|
||||||
{
|
{
|
||||||
return self::exitCode() === self::SUCCESS_EXIT;
|
return self::exitCode($configuration, $result) === self::SUCCESS_EXIT;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the test execution's exit code.
|
* Get the test execution's exit code.
|
||||||
*/
|
*/
|
||||||
public static function exitCode(): int
|
public static function exitCode(Configuration $configuration, TestResult $result): int
|
||||||
{
|
{
|
||||||
$result = Facade::result();
|
|
||||||
|
|
||||||
$returnCode = self::FAILURE_EXIT;
|
$returnCode = self::FAILURE_EXIT;
|
||||||
|
|
||||||
if ($result->wasSuccessfulIgnoringPhpunitWarnings()
|
if ($result->wasSuccessfulIgnoringPhpunitWarnings()
|
||||||
@ -48,8 +46,6 @@ final class Result
|
|||||||
$returnCode = self::SUCCESS_EXIT;
|
$returnCode = self::SUCCESS_EXIT;
|
||||||
}
|
}
|
||||||
|
|
||||||
$configuration = Registry::get();
|
|
||||||
|
|
||||||
if ($configuration->failOnEmptyTestSuite() && $result->numberOfTests() === 0) {
|
if ($configuration->failOnEmptyTestSuite() && $result->numberOfTests() === 0) {
|
||||||
$returnCode = self::FAILURE_EXIT;
|
$returnCode = self::FAILURE_EXIT;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -73,7 +73,7 @@ final class Arr
|
|||||||
|
|
||||||
foreach ($array as $key => $value) {
|
foreach ($array as $key => $value) {
|
||||||
if (is_array($value) && $value !== []) {
|
if (is_array($value) && $value !== []) {
|
||||||
$results = array_merge($results, static::dot($value, $prepend.$key.'.'));
|
$results = array_merge($results, self::dot($value, $prepend.$key.'.'));
|
||||||
} else {
|
} else {
|
||||||
$results[$prepend.$value] = $value;
|
$results[$prepend.$value] = $value;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -42,7 +42,7 @@ final class Reflection
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (is_callable($method)) {
|
if (is_callable($method)) {
|
||||||
return static::bindCallable($method, $args);
|
return self::bindCallable($method, $args);
|
||||||
}
|
}
|
||||||
|
|
||||||
throw $exception;
|
throw $exception;
|
||||||
@ -72,7 +72,7 @@ final class Reflection
|
|||||||
|
|
||||||
return $test instanceof \PHPUnit\Framework\TestCase
|
return $test instanceof \PHPUnit\Framework\TestCase
|
||||||
? Closure::fromCallable($callable)->bindTo($test)(...$test->providedData())
|
? Closure::fromCallable($callable)->bindTo($test)(...$test->providedData())
|
||||||
: static::bindCallable($callable);
|
: self::bindCallable($callable);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@ -61,7 +61,8 @@ final class Str
|
|||||||
{
|
{
|
||||||
$code = self::PREFIX.str_replace(' ', '_', $code);
|
$code = self::PREFIX.str_replace(' ', '_', $code);
|
||||||
|
|
||||||
return (string) preg_replace('/[^A-Z_a-z0-9]/', '_', $code);
|
// sticks to PHP8.2 function naming rules https://www.php.net/manual/en/functions.user-defined.php
|
||||||
|
return (string) preg_replace('/[^a-zA-Z0-9_\x80-\xff]/', '_', $code);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@ -32,6 +32,7 @@ final class GitDirtyTestCaseFilter implements TestCaseFilter
|
|||||||
assert(is_array($this->changedFiles));
|
assert(is_array($this->changedFiles));
|
||||||
|
|
||||||
$relativePath = str_replace($this->projectRoot, '', $testCaseFilename);
|
$relativePath = str_replace($this->projectRoot, '', $testCaseFilename);
|
||||||
|
$relativePath = str_replace(DIRECTORY_SEPARATOR, '/', $relativePath);
|
||||||
|
|
||||||
if (str_starts_with($relativePath, '/')) {
|
if (str_starts_with($relativePath, '/')) {
|
||||||
$relativePath = substr($relativePath, 1);
|
$relativePath = substr($relativePath, 1);
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
##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[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:342|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:272|nat src/Support/ExceptionTrace.php:28|nat src/Concerns/Testable.php:272|nat src/Concerns/Testable.php:215|nat src/Kernel.php:84' 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']
|
||||||
##teamcity[testStarted name='it can be ignored because of no assertions' locationHint='pest_qn://tests/.tests/Failure.php::it can be ignored because of no assertions' flowId='1234']
|
##teamcity[testStarted name='it can be ignored because of no assertions' locationHint='pest_qn://tests/.tests/Failure.php::it can be ignored because of no assertions' flowId='1234']
|
||||||
##teamcity[testIgnored name='it can be ignored because of no assertions' message='This test did not perform any assertions' details='' flowId='1234']
|
##teamcity[testIgnored name='it can be ignored because of no assertions' message='This test did not perform any assertions' details='' flowId='1234']
|
||||||
@ -9,7 +9,7 @@
|
|||||||
##teamcity[testIgnored name='it can be ignored because it is skipped' message='This test was ignored.' details='' flowId='1234']
|
##teamcity[testIgnored name='it can be ignored because it is skipped' message='This test was ignored.' details='' flowId='1234']
|
||||||
##teamcity[testFinished name='it can be ignored because it is skipped' duration='100000' flowId='1234']
|
##teamcity[testFinished name='it can be ignored because it is skipped' duration='100000' flowId='1234']
|
||||||
##teamcity[testStarted name='it can fail' locationHint='pest_qn://tests/.tests/Failure.php::it can fail' flowId='1234']
|
##teamcity[testStarted name='it can fail' locationHint='pest_qn://tests/.tests/Failure.php::it can fail' flowId='1234']
|
||||||
##teamcity[testFailed name='it can fail' message='oh noo' details='at tests/.tests/Failure.php:18|nat src/Factories/TestCaseMethodFactory.php:100|nat src/Concerns/Testable.php:272|nat src/Support/ExceptionTrace.php:28|nat src/Concerns/Testable.php:272|nat src/Concerns/Testable.php:215|nat src/Kernel.php:84' flowId='1234']
|
##teamcity[testFailed name='it can fail' message='oh noo' details='at tests/.tests/Failure.php:18|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' flowId='1234']
|
||||||
##teamcity[testFinished name='it can fail' duration='100000' flowId='1234']
|
##teamcity[testFinished name='it can fail' duration='100000' flowId='1234']
|
||||||
##teamcity[testStarted name='it is not done yet' locationHint='pest_qn://tests/.tests/Failure.php::it is not done yet' flowId='1234']
|
##teamcity[testStarted name='it is not done yet' locationHint='pest_qn://tests/.tests/Failure.php::it is not done yet' flowId='1234']
|
||||||
##teamcity[testIgnored name='it is not done yet' message='This test was ignored.' details='' flowId='1234']
|
##teamcity[testIgnored name='it is not done yet' message='This test was ignored.' details='' flowId='1234']
|
||||||
|
|||||||
@ -1,7 +1,11 @@
|
|||||||
|
WARN Tests\Fixtures\CollisionTest
|
||||||
|
- error
|
||||||
|
- success
|
||||||
|
|
||||||
PASS Tests\Fixtures\DirectoryWithTests\ExampleTest
|
PASS Tests\Fixtures\DirectoryWithTests\ExampleTest
|
||||||
✓ it example 1
|
✓ it example 1
|
||||||
|
|
||||||
PASS Tests\Fixtures\ExampleTest
|
PASS Tests\Fixtures\ExampleTest
|
||||||
✓ it example 2
|
✓ it example 2
|
||||||
|
|
||||||
Tests: 2 passed (2 assertions)
|
Tests: 2 skipped, 2 passed (2 assertions)
|
||||||
|
|||||||
22
tests/.snapshots/collision-parallel.txt
Normal file
22
tests/.snapshots/collision-parallel.txt
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
|
||||||
|
⨯.
|
||||||
|
────────────────────────────────────────────────────────────────────────────
|
||||||
|
FAILED Tests\Fixtures\CollisionTest > success Exception
|
||||||
|
error
|
||||||
|
|
||||||
|
at tests/Fixtures/CollisionTest.php:4
|
||||||
|
1▕ <?php
|
||||||
|
2▕
|
||||||
|
3▕ test('error', function () {
|
||||||
|
➜ 4▕ throw new Exception('error');
|
||||||
|
5▕ })->skip(! isset($_SERVER['COLLISION_TEST']));
|
||||||
|
6▕
|
||||||
|
7▕ test('success', function () {
|
||||||
|
8▕ expect(true)->toBeTrue();
|
||||||
|
9▕ })->skip(! isset($_SERVER['COLLISION_TEST']));
|
||||||
|
|
||||||
|
1 tests/Fixtures/CollisionTest.php:4
|
||||||
|
2 src/Factories/TestCaseMethodFactory.php:100
|
||||||
|
|
||||||
|
|
||||||
|
Tests: 1 failed, 1 passed (1 assertions)
|
||||||
24
tests/.snapshots/collision.txt
Normal file
24
tests/.snapshots/collision.txt
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
|
||||||
|
FAIL Tests\Fixtures\CollisionTest
|
||||||
|
⨯ error
|
||||||
|
✓ success
|
||||||
|
────────────────────────────────────────────────────────────────────────────
|
||||||
|
FAILED Tests\Fixtures\CollisionTest > error Exception
|
||||||
|
error
|
||||||
|
|
||||||
|
at tests/Fixtures/CollisionTest.php:4
|
||||||
|
1▕ <?php
|
||||||
|
2▕
|
||||||
|
3▕ test('error', function () {
|
||||||
|
➜ 4▕ throw new Exception('error');
|
||||||
|
5▕ })->skip(! isset($_SERVER['COLLISION_TEST']));
|
||||||
|
6▕
|
||||||
|
7▕ test('success', function () {
|
||||||
|
8▕ expect(true)->toBeTrue();
|
||||||
|
9▕ })->skip(! isset($_SERVER['COLLISION_TEST']));
|
||||||
|
|
||||||
|
1 tests/Fixtures/CollisionTest.php:4
|
||||||
|
2 src/Factories/TestCaseMethodFactory.php:100
|
||||||
|
|
||||||
|
|
||||||
|
Tests: 1 failed, 1 passed (1 assertions)
|
||||||
@ -1,5 +1,5 @@
|
|||||||
|
|
||||||
Pest Testing Framework 2.0.1.
|
Pest Testing Framework 2.2.0.
|
||||||
|
|
||||||
USAGE: pest <file> [options]
|
USAGE: pest <file> [options]
|
||||||
|
|
||||||
@ -33,6 +33,7 @@
|
|||||||
--test-suffix [suffixes] Only search for test in files with specified suffix(es). Default: Test.php,.phpt
|
--test-suffix [suffixes] Only search for test in files with specified suffix(es). Default: Test.php,.phpt
|
||||||
|
|
||||||
EXECUTION OPTIONS:
|
EXECUTION OPTIONS:
|
||||||
|
--parallel ........................................... Run tests in parallel
|
||||||
--process-isolation ................ Run each test in a separate PHP process
|
--process-isolation ................ Run each test in a separate PHP process
|
||||||
--globals-backup ................. Backup and restore $GLOBALS for each test
|
--globals-backup ................. Backup and restore $GLOBALS for each test
|
||||||
--static-backup ......... Backup and restore static properties for each test
|
--static-backup ......... Backup and restore static properties for each test
|
||||||
|
|||||||
@ -4,6 +4,9 @@
|
|||||||
✓ dependencies
|
✓ dependencies
|
||||||
✓ contracts
|
✓ contracts
|
||||||
|
|
||||||
|
PASS Tests\Environments\Windows
|
||||||
|
✓ global functions are loaded
|
||||||
|
|
||||||
PASS Tests\Features\AfterAll
|
PASS Tests\Features\AfterAll
|
||||||
✓ deletes file after all
|
✓ deletes file after all
|
||||||
|
|
||||||
@ -331,12 +334,14 @@
|
|||||||
|
|
||||||
PASS Tests\Features\Expect\toBeGreatherThan
|
PASS Tests\Features\Expect\toBeGreatherThan
|
||||||
✓ passes
|
✓ passes
|
||||||
|
✓ passes with DateTime and DateTimeImmutable
|
||||||
✓ failures
|
✓ failures
|
||||||
✓ failures with custom message
|
✓ failures with custom message
|
||||||
✓ not failures
|
✓ not failures
|
||||||
|
|
||||||
PASS Tests\Features\Expect\toBeGreatherThanOrEqual
|
PASS Tests\Features\Expect\toBeGreatherThanOrEqual
|
||||||
✓ passes
|
✓ passes
|
||||||
|
✓ passes with DateTime and DateTimeImmutable
|
||||||
✓ failures
|
✓ failures
|
||||||
✓ failures with custom message
|
✓ failures with custom message
|
||||||
✓ not failures
|
✓ not failures
|
||||||
@ -379,12 +384,14 @@
|
|||||||
|
|
||||||
PASS Tests\Features\Expect\toBeLessThan
|
PASS Tests\Features\Expect\toBeLessThan
|
||||||
✓ passes
|
✓ passes
|
||||||
|
✓ passes with DateTime and DateTimeImmutable
|
||||||
✓ failures
|
✓ failures
|
||||||
✓ failures with custom message
|
✓ failures with custom message
|
||||||
✓ not failures
|
✓ not failures
|
||||||
|
|
||||||
PASS Tests\Features\Expect\toBeLessThanOrEqual
|
PASS Tests\Features\Expect\toBeLessThanOrEqual
|
||||||
✓ passes
|
✓ passes
|
||||||
|
✓ passes with DateTime and DateTimeImmutable
|
||||||
✓ failures
|
✓ failures
|
||||||
✓ failures with custom message
|
✓ failures with custom message
|
||||||
✓ not failures
|
✓ not failures
|
||||||
@ -772,6 +779,10 @@
|
|||||||
! warning → Undefined property: P\Tests\Features\Warnings::$fooqwdfwqdfqw
|
! warning → Undefined property: P\Tests\Features\Warnings::$fooqwdfwqdfqw
|
||||||
! user warning → This is a warning description
|
! user warning → This is a warning description
|
||||||
|
|
||||||
|
WARN Tests\Fixtures\CollisionTest
|
||||||
|
- error
|
||||||
|
- success
|
||||||
|
|
||||||
PASS Tests\Fixtures\DirectoryWithTests\ExampleTest
|
PASS Tests\Fixtures\DirectoryWithTests\ExampleTest
|
||||||
✓ it example 1
|
✓ it example 1
|
||||||
|
|
||||||
@ -837,15 +848,6 @@
|
|||||||
✓ 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
|
||||||
|
|
||||||
WARN Tests\Unit\ConfigLoader
|
|
||||||
✓ it fallbacks to default path if no phpunit file is found
|
|
||||||
- it fallbacks to default path if phpunit is not a valid XML
|
|
||||||
- it fallbacks to default path if failing to read phpunit content
|
|
||||||
- it fallbacks to default path if there is no test suites directory
|
|
||||||
- it fallbacks to default path if test suite directory has no value
|
|
||||||
- it fallbacks to default path if test suite directory does not exist
|
|
||||||
- it returns the parent folder of first test suite directory
|
|
||||||
|
|
||||||
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
|
||||||
|
|
||||||
@ -916,6 +918,52 @@
|
|||||||
✓ 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
|
||||||
|
✓ ふ+が+
|
||||||
|
✓ ほげ
|
||||||
|
✓ 卜竹弓一十山
|
||||||
|
✓ アゴデヸ
|
||||||
|
✓ !p8VrB
|
||||||
|
✓ &xe6VeKWF#n4
|
||||||
|
✓ %%HurHUnw7zM!
|
||||||
|
✓ rundeliekend
|
||||||
|
✓ g%%c!Jt9$fy#Kf
|
||||||
|
✓ NRs*Gz2@hmB$W$BPD%%b2U%3P%z%apnwSX
|
||||||
|
✓ ÀĤ{¼÷
|
||||||
|
✓ ìèéàòç
|
||||||
|
✓ زهراء المعادي
|
||||||
|
✓ الجبيهه
|
||||||
|
✓ الظهران
|
||||||
|
✓ Каролин
|
||||||
|
✓ অ্যান্টার্কটিকা
|
||||||
|
✓ Frýdek-Místek"
|
||||||
|
✓ Allingåbro&
|
||||||
|
✓ Κεντροαφρικανική Δημοκρατία
|
||||||
|
✓ آذربایجان غربی
|
||||||
|
✓ זימבבואה
|
||||||
|
✓ Belišće
|
||||||
|
✓ Գվատեմալա
|
||||||
|
✓ パプアニューギニア
|
||||||
|
✓ 富山県
|
||||||
|
✓ Қарағанды
|
||||||
|
✓ Қостанай
|
||||||
|
✓ 안양시 동안구
|
||||||
|
✓ Itālija
|
||||||
|
✓ Honningsvåg
|
||||||
|
✓ Águeda
|
||||||
|
✓ Râșcani
|
||||||
|
✓ Năsăud
|
||||||
|
✓ Орехово-Зуево
|
||||||
|
✓ Čereňany
|
||||||
|
✓ Moravče
|
||||||
|
✓ Šentjernej
|
||||||
|
✓ Врање
|
||||||
|
✓ Крушевац
|
||||||
|
✓ Åkersberga
|
||||||
|
✓ บอสเนียและเฮอร์เซโกวีนา
|
||||||
|
✓ Birleşik Arap Emirlikleri
|
||||||
|
✓ Німеччина
|
||||||
|
✓ Nam Định
|
||||||
|
✓ 呼和浩特
|
||||||
|
|
||||||
PASS Tests\Unit\TestSuite
|
PASS Tests\Unit\TestSuite
|
||||||
✓ it does not allow to add the same test description twice
|
✓ it does not allow to add the same test description twice
|
||||||
@ -925,6 +973,10 @@
|
|||||||
PASS Tests\Visual\BeforeEachTestName
|
PASS Tests\Visual\BeforeEachTestName
|
||||||
✓ latest description
|
✓ latest description
|
||||||
|
|
||||||
|
PASS Tests\Visual\Collision
|
||||||
|
✓ collision with ([''])
|
||||||
|
✓ collision with (['--parallel'])
|
||||||
|
|
||||||
PASS Tests\Visual\Help
|
PASS Tests\Visual\Help
|
||||||
✓ visual snapshot of help command output
|
✓ visual snapshot of help command output
|
||||||
|
|
||||||
@ -950,4 +1002,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, 18 skipped, 649 passed (1591 assertions)
|
Tests: 2 deprecated, 3 warnings, 4 incomplete, 1 notice, 4 todos, 14 skipped, 701 passed (1698 assertions)
|
||||||
@ -1,3 +1,3 @@
|
|||||||
|
|
||||||
Pest Testing Framework 2.0.1.
|
Pest Testing Framework 2.2.0.
|
||||||
|
|
||||||
|
|||||||
5
tests/Environments/Windows.php
Normal file
5
tests/Environments/Windows.php
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
test('global functions are loaded', function () {
|
||||||
|
expect(helper_returns_string())->toBeString();
|
||||||
|
});
|
||||||
@ -7,6 +7,15 @@ test('passes', function () {
|
|||||||
expect(4)->toBeGreaterThan(3.9);
|
expect(4)->toBeGreaterThan(3.9);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
test('passes with DateTime and DateTimeImmutable', function () {
|
||||||
|
$now = new DateTime();
|
||||||
|
$past = (new DateTimeImmutable())->modify('-1 day');
|
||||||
|
|
||||||
|
expect($now)->toBeGreaterThan($past);
|
||||||
|
|
||||||
|
expect($past)->not->toBeGreaterThan($now);
|
||||||
|
});
|
||||||
|
|
||||||
test('failures', function () {
|
test('failures', function () {
|
||||||
expect(4)->toBeGreaterThan(4);
|
expect(4)->toBeGreaterThan(4);
|
||||||
})->throws(ExpectationFailedException::class);
|
})->throws(ExpectationFailedException::class);
|
||||||
|
|||||||
@ -7,6 +7,17 @@ test('passes', function () {
|
|||||||
expect(4)->toBeGreaterThanOrEqual(4);
|
expect(4)->toBeGreaterThanOrEqual(4);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
test('passes with DateTime and DateTimeImmutable', function () {
|
||||||
|
$now = new DateTime();
|
||||||
|
$past = (new DateTimeImmutable())->modify('-1 day');
|
||||||
|
|
||||||
|
expect($now)->toBeGreaterThanOrEqual($now);
|
||||||
|
|
||||||
|
expect($now)->toBeGreaterThanOrEqual($past);
|
||||||
|
|
||||||
|
expect($past)->not->toBeGreaterThanOrEqual($now);
|
||||||
|
});
|
||||||
|
|
||||||
test('failures', function () {
|
test('failures', function () {
|
||||||
expect(4)->toBeGreaterThanOrEqual(4.1);
|
expect(4)->toBeGreaterThanOrEqual(4.1);
|
||||||
})->throws(ExpectationFailedException::class);
|
})->throws(ExpectationFailedException::class);
|
||||||
|
|||||||
@ -7,6 +7,15 @@ test('passes', function () {
|
|||||||
expect(4)->toBeLessThan(5);
|
expect(4)->toBeLessThan(5);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
test('passes with DateTime and DateTimeImmutable', function () {
|
||||||
|
$now = new DateTime();
|
||||||
|
$past = (new DateTimeImmutable())->modify('-1 day');
|
||||||
|
|
||||||
|
expect($past)->toBeLessThan($now);
|
||||||
|
|
||||||
|
expect($now)->not->toBeLessThan($now);
|
||||||
|
});
|
||||||
|
|
||||||
test('failures', function () {
|
test('failures', function () {
|
||||||
expect(4)->toBeLessThan(4);
|
expect(4)->toBeLessThan(4);
|
||||||
})->throws(ExpectationFailedException::class);
|
})->throws(ExpectationFailedException::class);
|
||||||
|
|||||||
@ -7,6 +7,17 @@ test('passes', function () {
|
|||||||
expect(4)->toBeLessThanOrEqual(4);
|
expect(4)->toBeLessThanOrEqual(4);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
test('passes with DateTime and DateTimeImmutable', function () {
|
||||||
|
$now = new DateTime();
|
||||||
|
$past = (new DateTimeImmutable())->modify('-1 day');
|
||||||
|
|
||||||
|
expect($now)->toBeLessThanOrEqual($now);
|
||||||
|
|
||||||
|
expect($past)->toBeLessThanOrEqual($now);
|
||||||
|
|
||||||
|
expect($now)->not->toBeLessThanOrEqual($past);
|
||||||
|
});
|
||||||
|
|
||||||
test('failures', function () {
|
test('failures', function () {
|
||||||
expect(4)->toBeLessThanOrEqual(3.9);
|
expect(4)->toBeLessThanOrEqual(3.9);
|
||||||
})->throws(ExpectationFailedException::class);
|
})->throws(ExpectationFailedException::class);
|
||||||
|
|||||||
9
tests/Fixtures/CollisionTest.php
Normal file
9
tests/Fixtures/CollisionTest.php
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
test('error', function () {
|
||||||
|
throw new Exception('error');
|
||||||
|
})->skip(! isset($_SERVER['COLLISION_TEST']));
|
||||||
|
|
||||||
|
test('success', function () {
|
||||||
|
expect(true)->toBeTrue();
|
||||||
|
})->skip(! isset($_SERVER['COLLISION_TEST']));
|
||||||
@ -25,3 +25,8 @@ uses()
|
|||||||
$_SERVER['globalHook']->calls->afterAll++;
|
$_SERVER['globalHook']->calls->afterAll++;
|
||||||
})
|
})
|
||||||
->in('Hooks');
|
->in('Hooks');
|
||||||
|
|
||||||
|
function helper_returns_string()
|
||||||
|
{
|
||||||
|
return 'string';
|
||||||
|
}
|
||||||
|
|||||||
@ -1,19 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
use Pest\ConfigLoader;
|
|
||||||
use Pest\Support\Reflection;
|
|
||||||
|
|
||||||
it('fallbacks to default path if no phpunit file is found', function () {
|
|
||||||
$instance = new ConfigLoader('fake-path');
|
|
||||||
|
|
||||||
expect(Reflection::getPropertyValue($instance, 'config'))->toBeNull();
|
|
||||||
expect($instance->getConfigurationFilePath())->toBeFalse();
|
|
||||||
expect($instance->getTestsDirectory())->toBe(ConfigLoader::DEFAULT_TESTS_PATH);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('fallbacks to default path if phpunit is not a valid XML')->skip();
|
|
||||||
it('fallbacks to default path if failing to read phpunit content')->skip();
|
|
||||||
it('fallbacks to default path if there is no test suites directory')->skip();
|
|
||||||
it('fallbacks to default path if test suite directory has no value')->skip();
|
|
||||||
it('fallbacks to default path if test suite directory does not exist')->skip();
|
|
||||||
it('returns the parent folder of first test suite directory')->skip();
|
|
||||||
@ -11,3 +11,60 @@ it('may start with P', function (string $real, string $toBePrinted) {
|
|||||||
['PPPackages\Foo', 'PPPackages\Foo'],
|
['PPPackages\Foo', 'PPPackages\Foo'],
|
||||||
['PPPackages\Foo', 'PPPackages\Foo'],
|
['PPPackages\Foo', 'PPPackages\Foo'],
|
||||||
]);
|
]);
|
||||||
|
|
||||||
|
$names = [
|
||||||
|
'ふ+が+' => '__pest_evaluable_ふ_が_',
|
||||||
|
'ほげ' => '__pest_evaluable_ほげ',
|
||||||
|
'卜竹弓一十山' => '__pest_evaluable_卜竹弓一十山',
|
||||||
|
'アゴデヸ' => '__pest_evaluable_アゴデヸ',
|
||||||
|
'!p8VrB' => '__pest_evaluable__p8VrB',
|
||||||
|
'&xe6VeKWF#n4' => '__pest_evaluable__xe6VeKWF_n4',
|
||||||
|
'%%HurHUnw7zM!' => '__pest_evaluable___HurHUnw7zM_',
|
||||||
|
'rundeliekend' => '__pest_evaluable_rundeliekend',
|
||||||
|
'g%%c!Jt9$fy#Kf' => '__pest_evaluable_g__c_Jt9_fy_Kf',
|
||||||
|
'NRs*Gz2@hmB$W$BPD%%b2U%3P%z%apnwSX' => '__pest_evaluable_NRs_Gz2_hmB_W_BPD__b2U_3P_z_apnwSX',
|
||||||
|
'ÀĤ{¼÷' => '__pest_evaluable_ÀĤ_¼÷',
|
||||||
|
'ìèéàòç' => '__pest_evaluable_ìèéàòç',
|
||||||
|
'زهراء المعادي' => '__pest_evaluable_زهراء_المعادي',
|
||||||
|
'الجبيهه' => '__pest_evaluable_الجبيهه',
|
||||||
|
'الظهران' => '__pest_evaluable_الظهران',
|
||||||
|
'Каролин' => '__pest_evaluable_Каролин',
|
||||||
|
'অ্যান্টার্কটিকা' => '__pest_evaluable_অ্যান্টার্কটিকা',
|
||||||
|
'Frýdek-Místek"' => '__pest_evaluable_Frýdek_Místek_',
|
||||||
|
'Allingåbro&' => '__pest_evaluable_Allingåbro_',
|
||||||
|
'Κεντροαφρικανική Δημοκρατία' => '__pest_evaluable_Κεντροαφρικανική_Δημοκρατία',
|
||||||
|
'آذربایجان غربی' => '__pest_evaluable_آذربایجان_غربی',
|
||||||
|
'זימבבואה' => '__pest_evaluable_זימבבואה',
|
||||||
|
'Belišće' => '__pest_evaluable_Belišće',
|
||||||
|
'Գվատեմալա' => '__pest_evaluable_Գվատեմալա',
|
||||||
|
'パプアニューギニア' => '__pest_evaluable_パプアニューギニア',
|
||||||
|
'富山県' => '__pest_evaluable_富山県',
|
||||||
|
'Қарағанды' => '__pest_evaluable_Қарағанды',
|
||||||
|
'Қостанай' => '__pest_evaluable_Қостанай',
|
||||||
|
'안양시 동안구' => '__pest_evaluable_안양시_동안구',
|
||||||
|
'Itālija' => '__pest_evaluable_Itālija',
|
||||||
|
'Honningsvåg' => '__pest_evaluable_Honningsvåg',
|
||||||
|
'Águeda' => '__pest_evaluable_Águeda',
|
||||||
|
'Râșcani' => '__pest_evaluable_Râșcani',
|
||||||
|
'Năsăud' => '__pest_evaluable_Năsăud',
|
||||||
|
'Орехово-Зуево' => '__pest_evaluable_Орехово_Зуево',
|
||||||
|
'Čereňany' => '__pest_evaluable_Čereňany',
|
||||||
|
'Moravče' => '__pest_evaluable_Moravče',
|
||||||
|
'Šentjernej' => '__pest_evaluable_Šentjernej',
|
||||||
|
'Врање' => '__pest_evaluable_Врање',
|
||||||
|
'Крушевац' => '__pest_evaluable_Крушевац',
|
||||||
|
'Åkersberga' => '__pest_evaluable_Åkersberga',
|
||||||
|
'บอสเนียและเฮอร์เซโกวีนา' => '__pest_evaluable_บอสเนียและเฮอร์เซโกวีนา',
|
||||||
|
'Birleşik Arap Emirlikleri' => '__pest_evaluable_Birleşik_Arap_Emirlikleri',
|
||||||
|
'Німеччина' => '__pest_evaluable_Німеччина',
|
||||||
|
'Nam Định' => '__pest_evaluable_Nam_Định',
|
||||||
|
'呼和浩特' => '__pest_evaluable_呼和浩特',
|
||||||
|
];
|
||||||
|
|
||||||
|
foreach ($names as $name => $methodName) {
|
||||||
|
test($name)
|
||||||
|
->expect(fn () => static::getLatestPrintableTestCaseMethodName())
|
||||||
|
->toBe($name)
|
||||||
|
->and(fn () => $this->name())
|
||||||
|
->toBe($methodName);
|
||||||
|
}
|
||||||
|
|||||||
42
tests/Visual/Collision.php
Normal file
42
tests/Visual/Collision.php
Normal file
@ -0,0 +1,42 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
test('collision', function (array $arguments) {
|
||||||
|
$snapshot = __DIR__.'/../.snapshots/collision.txt';
|
||||||
|
|
||||||
|
if (in_array('--parallel', $arguments)) {
|
||||||
|
$snapshot = __DIR__.'/../.snapshots/collision-parallel.txt';
|
||||||
|
}
|
||||||
|
|
||||||
|
$output = function () use ($arguments) {
|
||||||
|
$process = (new Symfony\Component\Process\Process(
|
||||||
|
array_merge(['php', 'bin/pest', 'tests/Fixtures/CollisionTest.php'], $arguments),
|
||||||
|
null,
|
||||||
|
['COLLISION_PRINTER' => 'DefaultPrinter', 'COLLISION_IGNORE_DURATION' => 'true', 'COLLISION_TEST' => true]
|
||||||
|
));
|
||||||
|
|
||||||
|
$process->run();
|
||||||
|
|
||||||
|
return preg_replace('#\\x1b[[][^A-Za-z]*[A-Za-z]#', '', $process->getOutput());
|
||||||
|
};
|
||||||
|
|
||||||
|
if (getenv('REBUILD_SNAPSHOTS')) {
|
||||||
|
$outputContent = explode("\n", $output());
|
||||||
|
array_pop($outputContent);
|
||||||
|
array_pop($outputContent);
|
||||||
|
array_pop($outputContent);
|
||||||
|
|
||||||
|
if (in_array('--parallel', $arguments)) {
|
||||||
|
array_pop($outputContent);
|
||||||
|
array_pop($outputContent);
|
||||||
|
}
|
||||||
|
|
||||||
|
file_put_contents($snapshot, implode("\n", $outputContent));
|
||||||
|
|
||||||
|
$this->markTestSkipped('Snapshot rebuilt.');
|
||||||
|
}
|
||||||
|
|
||||||
|
expect($output())->toContain(file_get_contents($snapshot));
|
||||||
|
})->with([
|
||||||
|
[['']],
|
||||||
|
[['--parallel']],
|
||||||
|
])->skip(PHP_OS_FAMILY === 'Windows');
|
||||||
@ -9,12 +9,12 @@ $run = function () {
|
|||||||
|
|
||||||
$process->run();
|
$process->run();
|
||||||
|
|
||||||
expect($process->getExitCode())->toBe(0);
|
// expect($process->getExitCode())->toBe(0);
|
||||||
|
|
||||||
return preg_replace('#\\x1b[[][^A-Za-z]*[A-Za-z]#', '', $process->getOutput());
|
return preg_replace('#\\x1b[[][^A-Za-z]*[A-Za-z]#', '', $process->getOutput());
|
||||||
};
|
};
|
||||||
|
|
||||||
test('parallel', function () use ($run) {
|
test('parallel', function () use ($run) {
|
||||||
expect($run())->toContain('Tests: 2 deprecated, 3 warnings, 4 incomplete, 1 notice, 4 todos, 15 skipped, 640 passed (1578 assertions)')
|
expect($run())->toContain('Tests: 2 deprecated, 3 warnings, 4 incomplete, 1 notice, 4 todos, 11 skipped, 690 passed (1684 assertions)')
|
||||||
->toContain('Parallel: 3 processes');
|
->toContain('Parallel: 3 processes');
|
||||||
})->skip(PHP_OS_FAMILY === 'Windows');
|
})->skip(PHP_OS_FAMILY === 'Windows');
|
||||||
|
|||||||
Reference in New Issue
Block a user