mirror of
https://github.com/pestphp/pest.git
synced 2026-03-06 07:47:22 +01:00
feat: adds pest function
This commit is contained in:
@ -91,6 +91,7 @@
|
|||||||
"extra": {
|
"extra": {
|
||||||
"pest": {
|
"pest": {
|
||||||
"plugins": [
|
"plugins": [
|
||||||
|
"Pest\\Plugins\\Configuration",
|
||||||
"Pest\\Plugins\\Bail",
|
"Pest\\Plugins\\Bail",
|
||||||
"Pest\\Plugins\\Cache",
|
"Pest\\Plugins\\Cache",
|
||||||
"Pest\\Plugins\\Coverage",
|
"Pest\\Plugins\\Coverage",
|
||||||
|
|||||||
31
resources/base-phpunit.xml
Normal file
31
resources/base-phpunit.xml
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<phpunit xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
|
xsi:noNamespaceSchemaLocation="vendor/phpunit/phpunit/phpunit.xsd"
|
||||||
|
bootstrap="vendor/autoload.php"
|
||||||
|
colors="true"
|
||||||
|
>
|
||||||
|
<testsuites>
|
||||||
|
<testsuite name="Default">
|
||||||
|
<directory>tests/</directory>
|
||||||
|
</testsuite>
|
||||||
|
</testsuites>
|
||||||
|
<source>
|
||||||
|
<include>
|
||||||
|
<directory>app</directory>
|
||||||
|
<directory>src</directory>
|
||||||
|
</include>
|
||||||
|
</source>
|
||||||
|
<php>
|
||||||
|
<env name="APP_ENV" value="testing"/>
|
||||||
|
<env name="APP_MAINTENANCE_DRIVER" value="file"/>
|
||||||
|
<env name="BCRYPT_ROUNDS" value="4"/>
|
||||||
|
<env name="CACHE_STORE" value="array"/>
|
||||||
|
<!-- <env name="DB_CONNECTION" value="sqlite"/> -->
|
||||||
|
<!-- <env name="DB_DATABASE" value=":memory:"/> -->
|
||||||
|
<env name="MAIL_MAILER" value="array"/>
|
||||||
|
<env name="PULSE_ENABLED" value="false"/>
|
||||||
|
<env name="QUEUE_CONNECTION" value="sync"/>
|
||||||
|
<env name="SESSION_DRIVER" value="array"/>
|
||||||
|
<env name="TELESCOPE_ENABLED" value="false"/>
|
||||||
|
</php>
|
||||||
|
</phpunit>
|
||||||
71
src/Configuration.php
Normal file
71
src/Configuration.php
Normal file
@ -0,0 +1,71 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace Pest;
|
||||||
|
|
||||||
|
use Pest\PendingCalls\UsesCall;
|
||||||
|
use Pest\Support\Backtrace;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @internal
|
||||||
|
*/
|
||||||
|
final class Configuration
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* The instance of the configuration.
|
||||||
|
*/
|
||||||
|
private static ?Configuration $instance = null;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the instance of the configuration.
|
||||||
|
*/
|
||||||
|
public static function getInstance(): Configuration
|
||||||
|
{
|
||||||
|
return self::$instance ??= new Configuration(
|
||||||
|
Backtrace::file(),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a new configuration instance.
|
||||||
|
*/
|
||||||
|
private function __construct(
|
||||||
|
private readonly string $filename,
|
||||||
|
) {
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the configuration of a certain folder.
|
||||||
|
*/
|
||||||
|
public function in(string ...$targets): UsesCall
|
||||||
|
{
|
||||||
|
return (new UsesCall($this->filename, []))->in(...$targets);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Depending on where is called, it will extend the given classes and traits globally or locally.
|
||||||
|
*/
|
||||||
|
public function extend(string ...$classAndTraits): UsesCall
|
||||||
|
{
|
||||||
|
return (new UsesCall($this->filename, array_values($classAndTraits)))
|
||||||
|
->in($this->filename)
|
||||||
|
->extend(...$classAndTraits);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Depending on where is called, it will extend the given classes and traits globally or locally.
|
||||||
|
*/
|
||||||
|
public function use(string ...$classAndTraits): UsesCall
|
||||||
|
{
|
||||||
|
return $this->extend(...$classAndTraits);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the theme configuration.
|
||||||
|
*/
|
||||||
|
public function theme(): Configuration\Theme
|
||||||
|
{
|
||||||
|
return new Configuration\Theme();
|
||||||
|
}
|
||||||
|
}
|
||||||
23
src/Configuration/Theme.php
Normal file
23
src/Configuration/Theme.php
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace Pest\Configuration;
|
||||||
|
|
||||||
|
use NunoMaduro\Collision\Adapters\Phpunit\Printers\DefaultPrinter;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @internal
|
||||||
|
*/
|
||||||
|
final readonly class Theme
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Sets the theme to compact.
|
||||||
|
*/
|
||||||
|
public function compact(): self
|
||||||
|
{
|
||||||
|
DefaultPrinter::compact(true);
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -3,6 +3,7 @@
|
|||||||
declare(strict_types=1);
|
declare(strict_types=1);
|
||||||
|
|
||||||
use Pest\Concerns\Expectable;
|
use Pest\Concerns\Expectable;
|
||||||
|
use Pest\Configuration;
|
||||||
use Pest\Exceptions\AfterAllWithinDescribe;
|
use Pest\Exceptions\AfterAllWithinDescribe;
|
||||||
use Pest\Exceptions\BeforeAllWithinDescribe;
|
use Pest\Exceptions\BeforeAllWithinDescribe;
|
||||||
use Pest\Expectation;
|
use Pest\Expectation;
|
||||||
@ -108,6 +109,16 @@ if (! function_exists('uses')) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (! function_exists('pest')) {
|
||||||
|
/**
|
||||||
|
* Creates a new Pest configuration instance.
|
||||||
|
*/
|
||||||
|
function pest(): Configuration
|
||||||
|
{
|
||||||
|
return Configuration::getInstance();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (! function_exists('test')) {
|
if (! function_exists('test')) {
|
||||||
/**
|
/**
|
||||||
* Adds the given closure as a test. The first argument
|
* Adds the given closure as a test. The first argument
|
||||||
|
|||||||
@ -48,11 +48,14 @@ final class UsesCall
|
|||||||
*/
|
*/
|
||||||
public function __construct(
|
public function __construct(
|
||||||
private readonly string $filename,
|
private readonly string $filename,
|
||||||
private readonly array $classAndTraits
|
private array $classAndTraits
|
||||||
) {
|
) {
|
||||||
$this->targets = [$filename];
|
$this->targets = [$filename];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @deprecated Use `pest()->theme()->compact()` instead.
|
||||||
|
*/
|
||||||
public function compact(): self
|
public function compact(): self
|
||||||
{
|
{
|
||||||
DefaultPrinter::compact(true);
|
DefaultPrinter::compact(true);
|
||||||
@ -60,11 +63,31 @@ final class UsesCall
|
|||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Specifies the class or traits to use.
|
||||||
|
*
|
||||||
|
* @alias extend
|
||||||
|
*/
|
||||||
|
public function use(string ...$classAndTraits): self
|
||||||
|
{
|
||||||
|
return $this->extend(...$classAndTraits);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Specifies the class or traits to use.
|
||||||
|
*/
|
||||||
|
public function extend(string ...$classAndTraits): self
|
||||||
|
{
|
||||||
|
$this->classAndTraits = array_values($classAndTraits);
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The directories or file where the
|
* The directories or file where the
|
||||||
* class or traits should be used.
|
* class or traits should be used.
|
||||||
*/
|
*/
|
||||||
public function in(string ...$targets): void
|
public function in(string ...$targets): self
|
||||||
{
|
{
|
||||||
$targets = array_map(function (string $path): string {
|
$targets = array_map(function (string $path): string {
|
||||||
$startChar = DIRECTORY_SEPARATOR;
|
$startChar = DIRECTORY_SEPARATOR;
|
||||||
@ -92,6 +115,8 @@ final class UsesCall
|
|||||||
|
|
||||||
return $accumulator;
|
return $accumulator;
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
96
src/Plugins/Configuration.php
Normal file
96
src/Plugins/Configuration.php
Normal file
@ -0,0 +1,96 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace Pest\Plugins;
|
||||||
|
|
||||||
|
use DOMDocument;
|
||||||
|
use Pest\Contracts\Plugins\HandlesArguments;
|
||||||
|
use Pest\Contracts\Plugins\Terminable;
|
||||||
|
use Pest\Plugins\Concerns\HandleArguments;
|
||||||
|
use PHPUnit\TextUI\CliArguments\Builder as CliConfigurationBuilder;
|
||||||
|
use PHPUnit\TextUI\CliArguments\XmlConfigurationFileFinder;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @internal
|
||||||
|
*/
|
||||||
|
final class Configuration implements HandlesArguments, Terminable
|
||||||
|
{
|
||||||
|
use HandleArguments;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The base PHPUnit file.
|
||||||
|
*/
|
||||||
|
public const BASE_PHPUNIT_FILE = __DIR__
|
||||||
|
.DIRECTORY_SEPARATOR
|
||||||
|
.'..'
|
||||||
|
.DIRECTORY_SEPARATOR
|
||||||
|
.'..'
|
||||||
|
.DIRECTORY_SEPARATOR
|
||||||
|
.'resources/base-phpunit.xml';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handles the arguments, adding the cache directory and the cache result arguments.
|
||||||
|
*/
|
||||||
|
public function handleArguments(array $arguments): array
|
||||||
|
{
|
||||||
|
if ($this->hasArgument('--configuration', $arguments) || $this->hasCustomConfigurationFile()) {
|
||||||
|
return $arguments;
|
||||||
|
}
|
||||||
|
|
||||||
|
$arguments = $this->pushArgument('--configuration', $arguments);
|
||||||
|
|
||||||
|
return $this->pushArgument((string) realpath($this->fromGeneratedConfigurationFile()), $arguments);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the configuration file from the generated configuration file.
|
||||||
|
*/
|
||||||
|
private function fromGeneratedConfigurationFile(): string
|
||||||
|
{
|
||||||
|
$path = $this->getTempPhpunitXmlPath();
|
||||||
|
if (file_exists($path)) {
|
||||||
|
unlink($path);
|
||||||
|
}
|
||||||
|
|
||||||
|
$doc = new DOMDocument();
|
||||||
|
$doc->load(self::BASE_PHPUNIT_FILE);
|
||||||
|
|
||||||
|
$contents = $doc->saveXML();
|
||||||
|
|
||||||
|
assert(is_int(file_put_contents($path, $contents)));
|
||||||
|
|
||||||
|
return $path;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check if the configuration file is custom.
|
||||||
|
*/
|
||||||
|
private function hasCustomConfigurationFile(): bool
|
||||||
|
{
|
||||||
|
$cliConfiguration = (new CliConfigurationBuilder)->fromParameters([]);
|
||||||
|
$configurationFile = (new XmlConfigurationFileFinder)->find($cliConfiguration);
|
||||||
|
|
||||||
|
return is_string($configurationFile);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the temporary phpunit.xml path.
|
||||||
|
*/
|
||||||
|
private function getTempPhpunitXmlPath(): string
|
||||||
|
{
|
||||||
|
return getcwd().'/.pest.xml';
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Terminates the plugin.
|
||||||
|
*/
|
||||||
|
public function terminate(): void
|
||||||
|
{
|
||||||
|
$path = $this->getTempPhpunitXmlPath();
|
||||||
|
|
||||||
|
if (file_exists($path)) {
|
||||||
|
unlink($path);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -1272,6 +1272,12 @@
|
|||||||
✓ 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
|
||||||
|
|
||||||
|
PASS Tests\Unit\Configuration\In
|
||||||
|
✓ it proxies to uses call
|
||||||
|
|
||||||
|
PASS Tests\Unit\Configuration\Theme
|
||||||
|
✓ it creates a theme instance
|
||||||
|
|
||||||
PASS Tests\Unit\Console\Help
|
PASS Tests\Unit\Console\Help
|
||||||
✓ it outputs the help information when --help is used
|
✓ it outputs the help information when --help is used
|
||||||
|
|
||||||
@ -1455,4 +1461,4 @@
|
|||||||
WARN Tests\Visual\Version
|
WARN Tests\Visual\Version
|
||||||
- visual snapshot of help command output
|
- visual snapshot of help command output
|
||||||
|
|
||||||
Tests: 2 deprecated, 4 warnings, 5 incomplete, 2 notices, 13 todos, 24 skipped, 1040 passed (2561 assertions)
|
Tests: 2 deprecated, 4 warnings, 5 incomplete, 2 notices, 13 todos, 24 skipped, 1042 passed (2563 assertions)
|
||||||
@ -7,20 +7,21 @@ error_reporting(E_ALL);
|
|||||||
|
|
||||||
$GLOBALS['__PEST_INTERNAL_TEST_SUITE'] = true;
|
$GLOBALS['__PEST_INTERNAL_TEST_SUITE'] = true;
|
||||||
|
|
||||||
uses(CustomTestCaseInSubFolder::class)->in('PHPUnit/CustomTestCaseInSubFolders/SubFolder/SubFolder');
|
pest()->in('PHPUnit/CustomTestCaseInSubFolders/SubFolder/SubFolder')->use(CustomTestCaseInSubFolder::class);
|
||||||
|
|
||||||
// test case for all the directories inside PHPUnit/GlobPatternTests/SubFolder/
|
// test case for all the directories inside PHPUnit/GlobPatternTests/SubFolder/
|
||||||
uses(CustomTestCase::class)->in('PHPUnit/GlobPatternTests/SubFolder/*/');
|
pest()->in('PHPUnit/GlobPatternTests/SubFolder/*')->extend(CustomTestCase::class);
|
||||||
|
|
||||||
// test case for all the files that end with AsPattern.php inside PHPUnit/GlobPatternTests/SubFolder2/
|
// test case for all the files that end with AsPattern.php inside PHPUnit/GlobPatternTests/SubFolder2/
|
||||||
uses(CustomTestCase::class)->in('PHPUnit/GlobPatternTests/SubFolder2/*AsPattern.php');
|
pest()->in('PHPUnit/GlobPatternTests/SubFolder2/*AsPattern.php')->use(CustomTestCase::class);
|
||||||
|
|
||||||
uses()->group('integration')->in('Visual');
|
pest()->in('Visual')->group('integration');
|
||||||
|
|
||||||
// NOTE: global test value container to be mutated and checked across files, as needed
|
// NOTE: global test value container to be mutated and checked across files, as needed
|
||||||
$_SERVER['globalHook'] = (object) ['calls' => (object) ['beforeAll' => 0, 'afterAll' => 0]];
|
$_SERVER['globalHook'] = (object) ['calls' => (object) ['beforeAll' => 0, 'afterAll' => 0]];
|
||||||
|
|
||||||
uses()
|
pest()
|
||||||
|
->in('Hooks')
|
||||||
->beforeEach(function () {
|
->beforeEach(function () {
|
||||||
$this->baz = 0;
|
$this->baz = 0;
|
||||||
})
|
})
|
||||||
@ -34,10 +35,9 @@ uses()
|
|||||||
->afterAll(function () {
|
->afterAll(function () {
|
||||||
$_SERVER['globalHook']->afterAll = 0;
|
$_SERVER['globalHook']->afterAll = 0;
|
||||||
$_SERVER['globalHook']->calls->afterAll++;
|
$_SERVER['globalHook']->calls->afterAll++;
|
||||||
})
|
});
|
||||||
->in('Hooks');
|
|
||||||
|
|
||||||
uses()
|
pest()->in('Hooks')
|
||||||
->beforeEach(function () {
|
->beforeEach(function () {
|
||||||
expect($this)
|
expect($this)
|
||||||
->toHaveProperty('baz')
|
->toHaveProperty('baz')
|
||||||
@ -69,8 +69,7 @@ uses()
|
|||||||
->toBe(0);
|
->toBe(0);
|
||||||
|
|
||||||
$_SERVER['globalHook']->afterAll = 1;
|
$_SERVER['globalHook']->afterAll = 1;
|
||||||
})
|
});
|
||||||
->in('Hooks');
|
|
||||||
|
|
||||||
function helper_returns_string()
|
function helper_returns_string()
|
||||||
{
|
{
|
||||||
|
|||||||
9
tests/Unit/Configuration/In.php
Normal file
9
tests/Unit/Configuration/In.php
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
use Pest\PendingCalls\UsesCall;
|
||||||
|
|
||||||
|
it('proxies to uses call', function () {
|
||||||
|
$in = pest()->in();
|
||||||
|
|
||||||
|
expect($in)->toBeInstanceOf(UsesCall::class);
|
||||||
|
});
|
||||||
7
tests/Unit/Configuration/Theme.php
Normal file
7
tests/Unit/Configuration/Theme.php
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
it('creates a theme instance', function () {
|
||||||
|
$theme = pest()->theme();
|
||||||
|
|
||||||
|
expect($theme)->toBeInstanceOf(Pest\Configuration\Theme::class);
|
||||||
|
});
|
||||||
@ -16,7 +16,7 @@ $run = function () {
|
|||||||
|
|
||||||
test('parallel', function () use ($run) {
|
test('parallel', function () use ($run) {
|
||||||
expect($run('--exclude-group=integration'))
|
expect($run('--exclude-group=integration'))
|
||||||
->toContain('Tests: 2 deprecated, 4 warnings, 5 incomplete, 2 notices, 13 todos, 19 skipped, 1026 passed (2529 assertions)')
|
->toContain('Tests: 2 deprecated, 4 warnings, 5 incomplete, 2 notices, 13 todos, 19 skipped, 1028 passed (2531 assertions)')
|
||||||
->toContain('Parallel: 3 processes');
|
->toContain('Parallel: 3 processes');
|
||||||
})->skipOnWindows();
|
})->skipOnWindows();
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user