mirror of
https://github.com/pestphp/pest.git
synced 2026-03-06 07:47:22 +01:00
Merge branch 'master' into feature/add-container
This commit is contained in:
18
.github/workflows/changelog.yml
vendored
18
.github/workflows/changelog.yml
vendored
@ -21,6 +21,24 @@ jobs:
|
||||
token: ${{ secrets.CHANGELOG_KEY }}
|
||||
repository: pestphp/website
|
||||
path: pestphp-website
|
||||
- name: Read CHANGELOG.md
|
||||
id: package
|
||||
uses: juliangruber/read-file-action@v1
|
||||
with:
|
||||
path: ./CHANGELOG.md
|
||||
- name: Add file headers
|
||||
uses: DamianReeves/write-file-action@v1.0
|
||||
with:
|
||||
path: ./CHANGELOG.md
|
||||
contents: |
|
||||
---
|
||||
title: Changelog
|
||||
description: Changelog
|
||||
extends: _layouts.documentation
|
||||
section: content
|
||||
---
|
||||
${{ steps.package.outputs.content }}
|
||||
write-mode: overwrite
|
||||
- name: Copy CHANGELOG to website repository
|
||||
run: cp CHANGELOG.md pestphp-website/source/docs/changelog.md
|
||||
- name: Create Pull Request
|
||||
|
||||
2
.github/workflows/formats.yml
vendored
2
.github/workflows/formats.yml
vendored
@ -30,7 +30,7 @@ jobs:
|
||||
uses: shivammathur/setup-php@v2
|
||||
with:
|
||||
php-version: ${{ matrix.php }}
|
||||
extensions: mbstring, zip
|
||||
extensions: dom, mbstring, zip
|
||||
tools: prestissimo
|
||||
coverage: pcov
|
||||
|
||||
|
||||
2
.github/workflows/tests.yml
vendored
2
.github/workflows/tests.yml
vendored
@ -29,7 +29,7 @@ jobs:
|
||||
uses: shivammathur/setup-php@v2
|
||||
with:
|
||||
php-version: ${{ matrix.php }}
|
||||
extensions: mbstring, zip
|
||||
extensions: dom, mbstring, zip
|
||||
coverage: none
|
||||
|
||||
- name: Install Composer dependencies
|
||||
|
||||
9
bin/pest
9
bin/pest
@ -1,6 +1,7 @@
|
||||
#!/usr/bin/env php
|
||||
<?php declare(strict_types=1);
|
||||
|
||||
use NunoMaduro\Collision\Provider;
|
||||
use Pest\Actions\ValidatesEnvironment;
|
||||
use Pest\Console\Command;
|
||||
use Pest\Support\Container;
|
||||
@ -10,18 +11,18 @@ use Symfony\Component\Console\Output\OutputInterface;
|
||||
|
||||
(static function () {
|
||||
// Used when Pest is required using composer.
|
||||
$vendorPath = realpath(__DIR__ . '/../../../../vendor/autoload.php');
|
||||
$vendorPath = dirname(__DIR__, 4) . '/vendor/autoload.php';
|
||||
|
||||
// Used when Pest maintainers are running Pest tests.
|
||||
$localPath = realpath(__DIR__ . '/../vendor/autoload.php');
|
||||
$localPath = dirname(__DIR__) . '/vendor/autoload.php';
|
||||
|
||||
if ($vendorPath) {
|
||||
if (file_exists($vendorPath)) {
|
||||
include_once $vendorPath;
|
||||
} else {
|
||||
include_once $localPath;
|
||||
}
|
||||
|
||||
(new \NunoMaduro\Collision\Provider)->register();
|
||||
(new Provider())->register();
|
||||
|
||||
$rootPath = getcwd();
|
||||
|
||||
|
||||
@ -18,9 +18,9 @@
|
||||
],
|
||||
"require": {
|
||||
"php": "^7.3",
|
||||
"nunomaduro/collision": "^5.0",
|
||||
"pestphp/pest-plugin": "dev-master",
|
||||
"pestphp/pest-plugin-coverage": "dev-master",
|
||||
"nunomaduro/collision": "^5.0.0-BETA2",
|
||||
"pestphp/pest-plugin": "^0.2",
|
||||
"pestphp/pest-plugin-coverage": "^0.2",
|
||||
"phpunit/phpunit": "^9.1.4",
|
||||
"sebastian/environment": "^5.1"
|
||||
},
|
||||
@ -67,9 +67,9 @@
|
||||
"lint": "rector process src && php-cs-fixer fix -v",
|
||||
"test:lint": "php-cs-fixer fix -v --dry-run && rector process src --dry-run",
|
||||
"test:types": "phpstan analyse --ansi",
|
||||
"test:unit": "bin/pest --colors=always --exclude-group=integration",
|
||||
"test:integration": "bin/pest --colors=always --group=integration",
|
||||
"test:integration:snapshots": "REBUILD_SNAPSHOTS=true bin/pest --colors=always",
|
||||
"test:unit": "php bin/pest --colors=always --exclude-group=integration",
|
||||
"test:integration": "php bin/pest --colors=always --group=integration",
|
||||
"test:integration:snapshots": "REBUILD_SNAPSHOTS=true php bin/pest --colors=always",
|
||||
"test": [
|
||||
"@test:lint",
|
||||
"@test:types",
|
||||
|
||||
@ -158,16 +158,25 @@ final class TestCaseFactory
|
||||
*/
|
||||
public function makeClassFromFilename(string $filename): string
|
||||
{
|
||||
if ('\\' === DIRECTORY_SEPARATOR) {
|
||||
// In case Windows, strtolower drive name, like in UsesCall.
|
||||
$filename = (string) preg_replace_callback('~^(?P<drive>[a-z]+:\\\)~i', function ($match): string {
|
||||
return strtolower($match['drive']);
|
||||
}, $filename);
|
||||
}
|
||||
|
||||
$filename = (string) realpath($filename);
|
||||
$rootPath = TestSuite::getInstance()->rootPath;
|
||||
$relativePath = str_replace($rootPath . DIRECTORY_SEPARATOR, '', $filename);
|
||||
$relativePath = dirname(ucfirst($relativePath)) . DIRECTORY_SEPARATOR . basename($relativePath, '.php');
|
||||
$relativePath = str_replace(DIRECTORY_SEPARATOR, '\\', $relativePath);
|
||||
|
||||
// Strip out any %-encoded octets.
|
||||
$relativePath = (string) preg_replace('|%[a-fA-F0-9][a-fA-F0-9]|', '', $relativePath);
|
||||
|
||||
// Limit to A-Z, a-z, 0-9, '_', '-'.
|
||||
$relativePath = (string) preg_replace('/[^A-Za-z0-9.\/]/', '', $relativePath);
|
||||
|
||||
$classFQN = 'P\\' . basename(ucfirst(str_replace(DIRECTORY_SEPARATOR, '\\', $relativePath)), '.php');
|
||||
$relativePath = (string) preg_replace('/[^A-Za-z0-9.\\\]/', '', $relativePath);
|
||||
|
||||
$classFQN = 'P\\' . $relativePath;
|
||||
if (class_exists($classFQN)) {
|
||||
return $classFQN;
|
||||
}
|
||||
|
||||
@ -59,7 +59,17 @@ final class UsesCall
|
||||
public function in(string ...$targets): void
|
||||
{
|
||||
$targets = array_map(function ($path): string {
|
||||
return $path[0] === DIRECTORY_SEPARATOR
|
||||
$startChar = DIRECTORY_SEPARATOR;
|
||||
|
||||
if ('\\' === DIRECTORY_SEPARATOR || preg_match('~\A[A-Z]:(?![^/\\\\])~i', $path) > 0) {
|
||||
$path = (string) preg_replace_callback('~^(?P<drive>[a-z]+:\\\)~i', function ($match): string {
|
||||
return strtolower($match['drive']);
|
||||
}, $path);
|
||||
|
||||
$startChar = strtolower((string) preg_replace('~^([a-z]+:\\\).*$~i', '$1', __DIR__));
|
||||
}
|
||||
|
||||
return 0 === strpos($path, $startChar)
|
||||
? $path
|
||||
: implode(DIRECTORY_SEPARATOR, [
|
||||
dirname($this->filename),
|
||||
@ -68,12 +78,12 @@ final class UsesCall
|
||||
}, $targets);
|
||||
|
||||
$this->targets = array_map(function ($target): string {
|
||||
$realTarget = realpath($target);
|
||||
if ($realTarget === false) {
|
||||
$isValid = is_dir($target) || file_exists($target);
|
||||
if (!$isValid) {
|
||||
throw new InvalidUsesPath($target);
|
||||
}
|
||||
|
||||
return $realTarget;
|
||||
return (string) realpath($target);
|
||||
}, $targets);
|
||||
}
|
||||
|
||||
|
||||
@ -24,7 +24,7 @@ final class Backtrace
|
||||
$current = null;
|
||||
|
||||
foreach (debug_backtrace() as $trace) {
|
||||
if (Str::endsWith($trace[self::FILE], 'vendor/phpunit/phpunit/src/Util/FileLoader.php')) {
|
||||
if (Str::endsWith($trace[self::FILE], (string) realpath('vendor/phpunit/phpunit/src/Util/FileLoader.php'))) {
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
@ -83,7 +83,7 @@ final class TestSuite
|
||||
$this->afterEach = new AfterEachRepository();
|
||||
$this->afterAll = new AfterAllRepository();
|
||||
|
||||
$this->rootPath = $rootPath;
|
||||
$this->rootPath = (string) realpath($rootPath);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
7
tests/.snapshots/allows-to-run-a-directory.txt
Normal file
7
tests/.snapshots/allows-to-run-a-directory.txt
Normal file
@ -0,0 +1,7 @@
|
||||
PASS Tests\Fixtures\DirectoryWithTests\ExampleTest
|
||||
✓ it example 1
|
||||
|
||||
PASS Tests\Fixtures\ExampleTest
|
||||
✓ it example 2
|
||||
|
||||
Tests: 2 passed
|
||||
4
tests/.snapshots/allows-to-run-a-single-test.txt
Normal file
4
tests/.snapshots/allows-to-run-a-single-test.txt
Normal file
@ -0,0 +1,4 @@
|
||||
PASS Tests\Fixtures\DirectoryWithTests\ExampleTest
|
||||
✓ it example 1
|
||||
|
||||
Tests: 1 passed
|
||||
5
tests/.snapshots/disable-decorating-printer.txt
Normal file
5
tests/.snapshots/disable-decorating-printer.txt
Normal file
@ -0,0 +1,5 @@
|
||||
|
||||
PASS Tests\Fixtures\DirectoryWithTests\ExampleTest
|
||||
✓ [2mit example 1[22m
|
||||
|
||||
Tests: 1 passed
|
||||
5
tests/.snapshots/has-ascii-chars.txt
Normal file
5
tests/.snapshots/has-ascii-chars.txt
Normal file
@ -0,0 +1,5 @@
|
||||
|
||||
[30;42;1m PASS [39;49;22m[39m Tests\Fixtures\DirectoryWithTests\ExampleTest[39m
|
||||
[32;1m✓[39;22m[39m [2mit example 1[22m[39m
|
||||
|
||||
[37;1mTests: [39;22m[32;1m1 passed[39;22m
|
||||
@ -1,5 +1,5 @@
|
||||
|
||||
PASS Tests\CustomTestCase\PhpunitTest
|
||||
PASS Tests\CustomTestCase\ExecutedTest
|
||||
✓ that gets executed
|
||||
|
||||
PASS Tests\Features\AfterAll
|
||||
@ -24,7 +24,7 @@
|
||||
✓ it sets arrays
|
||||
✓ it gets bound to test case object with ('a')
|
||||
✓ it gets bound to test case object with ('b')
|
||||
✓ it truncates the description with (' fooo fooo fooo fooo fooo fooo fooo f...oo fooo')
|
||||
✓ it truncates the description with ('FoooFoooFoooFoooFoooFoooFoooF...ooFooo')
|
||||
✓ lazy datasets with (1)
|
||||
✓ lazy datasets with (2)
|
||||
✓ lazy datasets did the job right
|
||||
@ -40,10 +40,10 @@
|
||||
✓ eager wrapped registered datasets with (1)
|
||||
✓ eager wrapped registered datasets with (2)
|
||||
✓ eager registered wrapped datasets did the job right
|
||||
✓ lazy named datasets with ( bar object (...))
|
||||
✓ lazy named datasets with (Bar Object (...))
|
||||
|
||||
PASS Tests\Features\Exceptions
|
||||
✓ it gives access the the underlying expect exception
|
||||
✓ it gives access the the underlying expectException
|
||||
✓ it catch exceptions
|
||||
✓ it catch exceptions and messages
|
||||
|
||||
@ -64,8 +64,8 @@
|
||||
✓ it has bar
|
||||
|
||||
PASS Tests\Features\PendingHigherOrderTests
|
||||
✓ get 'foo' → get 'bar' → assert true true
|
||||
✓ get 'foo' → assert true true
|
||||
✓ get 'foo' → get 'bar' → assertTrue true
|
||||
✓ get 'foo' → assertTrue true
|
||||
|
||||
WARN Tests\Features\Skip
|
||||
✓ it do not skips
|
||||
@ -81,16 +81,16 @@
|
||||
✓ higher order message test
|
||||
|
||||
PASS Tests\Fixtures\DirectoryWithTests\ExampleTest
|
||||
✓ it example
|
||||
✓ it example 1
|
||||
|
||||
PASS Tests\Fixtures\ExampleTest
|
||||
✓ it example
|
||||
✓ it example 2
|
||||
|
||||
PASS Tests\PHPUnit\CustomTestCase\UsesPerDirectory
|
||||
✓ closure was bound to custom test case
|
||||
✓ closure was bound to CustomTestCase
|
||||
|
||||
PASS Tests\PHPUnit\CustomTestCaseInSubFolders\SubFolder\SubFolder\UsesPerSubDirectory
|
||||
✓ closure was bound to custom test case
|
||||
✓ closure was bound to CustomTestCase
|
||||
|
||||
PASS Tests\PHPUnit\CustomTestCaseInSubFolders\SubFolder2\UsesPerFile
|
||||
✓ custom traits can be used
|
||||
@ -137,7 +137,7 @@
|
||||
PASS Tests\Visual\SingleTestOrDirectory
|
||||
✓ allows to run a single test
|
||||
✓ allows to run a directory
|
||||
✓ it has ascii chars (decorated printer)
|
||||
✓ it has ascii chars
|
||||
✓ it disable decorating printer when colors is set to never
|
||||
|
||||
WARN Tests\Visual\Success
|
||||
|
||||
@ -1,3 +1,3 @@
|
||||
<?php
|
||||
|
||||
it('example')->assertTrue(true);
|
||||
it('example 1')->assertTrue(true);
|
||||
|
||||
@ -1,3 +1,3 @@
|
||||
<?php
|
||||
|
||||
it('example')->assertTrue(true);
|
||||
it('example 2')->assertTrue(true);
|
||||
|
||||
@ -7,7 +7,7 @@ namespace Tests\CustomTestCase;
|
||||
use function PHPUnit\Framework\assertTrue;
|
||||
use PHPUnit\Framework\TestCase;
|
||||
|
||||
class PhpunitTest extends TestCase
|
||||
class ExecutedTest extends TestCase
|
||||
{
|
||||
public static $executed = false;
|
||||
|
||||
@ -16,8 +16,8 @@ class PhpunitTest extends TestCase
|
||||
{
|
||||
self::$executed = true;
|
||||
|
||||
$this->assertTrue(true);
|
||||
assertTrue(true);
|
||||
}
|
||||
}
|
||||
|
||||
// register_shutdown_function(fn () => assertTrue(PhpunitTest::$executed));
|
||||
// register_shutdown_function(fn () => assertTrue(ExecutedTest::$executed));
|
||||
@ -2,53 +2,47 @@
|
||||
|
||||
use Symfony\Component\Process\Process;
|
||||
|
||||
$run = function (string $target) {
|
||||
$process = new Process(['./bin/pest', $target], dirname(__DIR__, 2));
|
||||
$run = function (string $target, $decorated = false) {
|
||||
$process = new Process(['php', 'bin/pest', $target], dirname(__DIR__, 2));
|
||||
|
||||
$process->run();
|
||||
|
||||
return preg_replace('#\\x1b[[][^A-Za-z]*[A-Za-z]#', '', $process->getOutput());
|
||||
return $decorated ? $process->getOutput() : preg_replace('#\\x1b[[][^A-Za-z]*[A-Za-z]#', '', $process->getOutput());
|
||||
};
|
||||
|
||||
test('allows to run a single test', function () use ($run) {
|
||||
assertStringContainsString(<<<EOF
|
||||
PASS Tests\Fixtures\DirectoryWithTests\ExampleTest
|
||||
✓ it example
|
||||
$snapshot = function ($name) {
|
||||
$testsPath = dirname(__DIR__);
|
||||
|
||||
Tests: 1 passed
|
||||
EOF, $run('tests/Fixtures/DirectoryWithTests/ExampleTest.php'));
|
||||
return file_get_contents(implode(DIRECTORY_SEPARATOR, [
|
||||
$testsPath,
|
||||
'.snapshots',
|
||||
"$name.txt",
|
||||
]));
|
||||
};
|
||||
|
||||
test('allows to run a single test', function () use ($run, $snapshot) {
|
||||
assertStringContainsString(
|
||||
$snapshot('allows-to-run-a-single-test'),
|
||||
$run('tests/Fixtures/DirectoryWithTests/ExampleTest.php'));
|
||||
});
|
||||
|
||||
test('allows to run a directory', function () use ($run) {
|
||||
assertStringContainsString(<<<EOF
|
||||
PASS Tests\Fixtures\DirectoryWithTests\ExampleTest
|
||||
✓ it example
|
||||
|
||||
PASS Tests\Fixtures\ExampleTest
|
||||
✓ it example
|
||||
|
||||
Tests: 2 passed
|
||||
EOF, $run('tests/Fixtures'));
|
||||
test('allows to run a directory', function () use ($run, $snapshot) {
|
||||
assertStringContainsString(
|
||||
$snapshot('allows-to-run-a-directory'),
|
||||
$run('tests/Fixtures')
|
||||
);
|
||||
});
|
||||
|
||||
it('has ascii chars (decorated printer)', function () {
|
||||
$process = new Process([
|
||||
'./bin/pest',
|
||||
'tests/Fixtures/DirectoryWithTests/ExampleTest.php',
|
||||
], dirname(__DIR__, 2));
|
||||
|
||||
$process->run();
|
||||
$output = $process->getOutput();
|
||||
assertStringContainsString(<<<EOF
|
||||
\e[30;42;1m PASS \e[39;49;22m\e[39m Tests\Fixtures\DirectoryWithTests\ExampleTest\e[39m
|
||||
\e[32;1m✓\e[39;22m\e[39m \e[2mit example\e[22m\e[39m
|
||||
|
||||
\e[37;1mTests: \e[39;22m\e[32;1m1 passed\e[39;22m
|
||||
EOF, $output);
|
||||
});
|
||||
|
||||
it('disable decorating printer when colors is set to never', function () {
|
||||
it('has ascii chars', function () use ($run, $snapshot) {
|
||||
assertStringContainsString(
|
||||
$snapshot('has-ascii-chars'),
|
||||
$run('tests/Fixtures/DirectoryWithTests/ExampleTest.php', true)
|
||||
);
|
||||
});
|
||||
|
||||
it('disable decorating printer when colors is set to never', function () use ($snapshot) {
|
||||
$process = new Process([
|
||||
'php',
|
||||
'./bin/pest',
|
||||
'--colors=never',
|
||||
'tests/Fixtures/DirectoryWithTests/ExampleTest.php',
|
||||
@ -56,10 +50,8 @@ it('disable decorating printer when colors is set to never', function () {
|
||||
$process->run();
|
||||
$output = $process->getOutput();
|
||||
|
||||
assertStringContainsString(<<<EOF
|
||||
PASS Tests\Fixtures\DirectoryWithTests\ExampleTest
|
||||
✓ \e[2mit example\e[22m
|
||||
|
||||
Tests: 1 passed
|
||||
EOF, $output);
|
||||
assertStringContainsString(
|
||||
$snapshot('disable-decorating-printer'),
|
||||
$output
|
||||
);
|
||||
});
|
||||
|
||||
@ -9,7 +9,7 @@ test('visual snapshot of test suite on success', function () {
|
||||
]);
|
||||
|
||||
$output = function () use ($testsPath) {
|
||||
$process = (new Symfony\Component\Process\Process(['./bin/pest'], dirname($testsPath), ['EXCLUDE' => 'integration', 'REBUILD_SNAPSHOTS' => false]));
|
||||
$process = (new Symfony\Component\Process\Process(['php', 'bin/pest'], dirname($testsPath), ['EXCLUDE' => 'integration', 'REBUILD_SNAPSHOTS' => false]));
|
||||
|
||||
$process->run();
|
||||
|
||||
@ -24,4 +24,5 @@ test('visual snapshot of test suite on success', function () {
|
||||
array_pop($output);
|
||||
assertStringContainsString(implode("\n", $output), file_get_contents($snapshot));
|
||||
}
|
||||
})->skip(!getenv('REBUILD_SNAPSHOTS') && getenv('EXCLUDE'));
|
||||
})->skip(!getenv('REBUILD_SNAPSHOTS') && getenv('EXCLUDE'))
|
||||
->skip(PHP_OS_FAMILY === 'Windows', 'File sorting algorithm causes different test order on Windows');
|
||||
|
||||
6
tests/Visual/foo.txt
Normal file
6
tests/Visual/foo.txt
Normal file
@ -0,0 +1,6 @@
|
||||
|
||||
[30;42;1m PASS [39;49;22m[39m Tests\Fixtures\DirectoryWithTests\ExampleTest[39m
|
||||
[32;1m✓[39;22m[39m [2mit example 1[22m[39m
|
||||
|
||||
[37;1mTests: [39;22m[32;1m1 passed[39;22m
|
||||
[37;1mTime: [39;22m[39m0.04s[39m
|
||||
Reference in New Issue
Block a user