Merge branch 'master' into feature/add-container

This commit is contained in:
Nuno Maduro
2020-06-05 22:39:02 +02:00
committed by GitHub
20 changed files with 146 additions and 88 deletions

View File

@ -21,6 +21,24 @@ jobs:
token: ${{ secrets.CHANGELOG_KEY }} token: ${{ secrets.CHANGELOG_KEY }}
repository: pestphp/website repository: pestphp/website
path: 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 - name: Copy CHANGELOG to website repository
run: cp CHANGELOG.md pestphp-website/source/docs/changelog.md run: cp CHANGELOG.md pestphp-website/source/docs/changelog.md
- name: Create Pull Request - name: Create Pull Request

View File

@ -30,7 +30,7 @@ jobs:
uses: shivammathur/setup-php@v2 uses: shivammathur/setup-php@v2
with: with:
php-version: ${{ matrix.php }} php-version: ${{ matrix.php }}
extensions: mbstring, zip extensions: dom, mbstring, zip
tools: prestissimo tools: prestissimo
coverage: pcov coverage: pcov

View File

@ -29,7 +29,7 @@ jobs:
uses: shivammathur/setup-php@v2 uses: shivammathur/setup-php@v2
with: with:
php-version: ${{ matrix.php }} php-version: ${{ matrix.php }}
extensions: mbstring, zip extensions: dom, mbstring, zip
coverage: none coverage: none
- name: Install Composer dependencies - name: Install Composer dependencies

View File

@ -1,6 +1,7 @@
#!/usr/bin/env php #!/usr/bin/env php
<?php declare(strict_types=1); <?php declare(strict_types=1);
use NunoMaduro\Collision\Provider;
use Pest\Actions\ValidatesEnvironment; use Pest\Actions\ValidatesEnvironment;
use Pest\Console\Command; use Pest\Console\Command;
use Pest\Support\Container; use Pest\Support\Container;
@ -10,18 +11,18 @@ use Symfony\Component\Console\Output\OutputInterface;
(static function () { (static function () {
// Used when Pest is required using composer. // 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. // 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; include_once $vendorPath;
} else { } else {
include_once $localPath; include_once $localPath;
} }
(new \NunoMaduro\Collision\Provider)->register(); (new Provider())->register();
$rootPath = getcwd(); $rootPath = getcwd();

View File

@ -18,9 +18,9 @@
], ],
"require": { "require": {
"php": "^7.3", "php": "^7.3",
"nunomaduro/collision": "^5.0", "nunomaduro/collision": "^5.0.0-BETA2",
"pestphp/pest-plugin": "dev-master", "pestphp/pest-plugin": "^0.2",
"pestphp/pest-plugin-coverage": "dev-master", "pestphp/pest-plugin-coverage": "^0.2",
"phpunit/phpunit": "^9.1.4", "phpunit/phpunit": "^9.1.4",
"sebastian/environment": "^5.1" "sebastian/environment": "^5.1"
}, },
@ -67,9 +67,9 @@
"lint": "rector process src && php-cs-fixer fix -v", "lint": "rector process src && php-cs-fixer fix -v",
"test:lint": "php-cs-fixer fix -v --dry-run && rector process src --dry-run", "test:lint": "php-cs-fixer fix -v --dry-run && rector process src --dry-run",
"test:types": "phpstan analyse --ansi", "test:types": "phpstan analyse --ansi",
"test:unit": "bin/pest --colors=always --exclude-group=integration", "test:unit": "php bin/pest --colors=always --exclude-group=integration",
"test:integration": "bin/pest --colors=always --group=integration", "test:integration": "php bin/pest --colors=always --group=integration",
"test:integration:snapshots": "REBUILD_SNAPSHOTS=true bin/pest --colors=always", "test:integration:snapshots": "REBUILD_SNAPSHOTS=true php bin/pest --colors=always",
"test": [ "test": [
"@test:lint", "@test:lint",
"@test:types", "@test:types",

View File

@ -158,16 +158,25 @@ final class TestCaseFactory
*/ */
public function makeClassFromFilename(string $filename): string 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; $rootPath = TestSuite::getInstance()->rootPath;
$relativePath = str_replace($rootPath . DIRECTORY_SEPARATOR, '', $filename); $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. // Strip out any %-encoded octets.
$relativePath = (string) preg_replace('|%[a-fA-F0-9][a-fA-F0-9]|', '', $relativePath); $relativePath = (string) preg_replace('|%[a-fA-F0-9][a-fA-F0-9]|', '', $relativePath);
// Limit to A-Z, a-z, 0-9, '_', '-'. // Limit to A-Z, a-z, 0-9, '_', '-'.
$relativePath = (string) preg_replace('/[^A-Za-z0-9.\/]/', '', $relativePath); $relativePath = (string) preg_replace('/[^A-Za-z0-9.\\\]/', '', $relativePath);
$classFQN = 'P\\' . basename(ucfirst(str_replace(DIRECTORY_SEPARATOR, '\\', $relativePath)), '.php');
$classFQN = 'P\\' . $relativePath;
if (class_exists($classFQN)) { if (class_exists($classFQN)) {
return $classFQN; return $classFQN;
} }

View File

@ -59,7 +59,17 @@ final class UsesCall
public function in(string ...$targets): void public function in(string ...$targets): void
{ {
$targets = array_map(function ($path): string { $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 ? $path
: implode(DIRECTORY_SEPARATOR, [ : implode(DIRECTORY_SEPARATOR, [
dirname($this->filename), dirname($this->filename),
@ -68,12 +78,12 @@ final class UsesCall
}, $targets); }, $targets);
$this->targets = array_map(function ($target): string { $this->targets = array_map(function ($target): string {
$realTarget = realpath($target); $isValid = is_dir($target) || file_exists($target);
if ($realTarget === false) { if (!$isValid) {
throw new InvalidUsesPath($target); throw new InvalidUsesPath($target);
} }
return $realTarget; return (string) realpath($target);
}, $targets); }, $targets);
} }

View File

@ -24,7 +24,7 @@ final class Backtrace
$current = null; $current = null;
foreach (debug_backtrace() as $trace) { 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; break;
} }

View File

@ -83,7 +83,7 @@ final class TestSuite
$this->afterEach = new AfterEachRepository(); $this->afterEach = new AfterEachRepository();
$this->afterAll = new AfterAllRepository(); $this->afterAll = new AfterAllRepository();
$this->rootPath = $rootPath; $this->rootPath = (string) realpath($rootPath);
} }
/** /**

View File

@ -0,0 +1,7 @@
PASS Tests\Fixtures\DirectoryWithTests\ExampleTest
✓ it example 1
PASS Tests\Fixtures\ExampleTest
✓ it example 2
Tests: 2 passed

View File

@ -0,0 +1,4 @@
PASS Tests\Fixtures\DirectoryWithTests\ExampleTest
✓ it example 1
Tests: 1 passed

View File

@ -0,0 +1,5 @@
PASS Tests\Fixtures\DirectoryWithTests\ExampleTest
it example 1
Tests: 1 passed

View File

@ -0,0 +1,5 @@
 PASS  Tests\Fixtures\DirectoryWithTests\ExampleTest
✓ it example 1
Tests: 1 passed

View File

@ -1,5 +1,5 @@
PASS Tests\CustomTestCase\PhpunitTest PASS Tests\CustomTestCase\ExecutedTest
✓ that gets executed ✓ that gets executed
PASS Tests\Features\AfterAll PASS Tests\Features\AfterAll
@ -24,7 +24,7 @@
✓ it sets arrays ✓ it sets arrays
✓ it gets bound to test case object with ('a') ✓ it gets bound to test case object with ('a')
✓ it gets bound to test case object with ('b') ✓ 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 (1)
✓ lazy datasets with (2) ✓ lazy datasets with (2)
✓ lazy datasets did the job right ✓ lazy datasets did the job right
@ -40,10 +40,10 @@
✓ eager wrapped registered datasets with (1) ✓ eager wrapped registered datasets with (1)
✓ eager wrapped registered datasets with (2) ✓ eager wrapped registered datasets with (2)
✓ eager registered wrapped datasets did the job right ✓ eager registered wrapped datasets did the job right
✓ lazy named datasets with ( bar object (...)) ✓ lazy named datasets with (Bar Object (...))
PASS Tests\Features\Exceptions 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
✓ it catch exceptions and messages ✓ it catch exceptions and messages
@ -64,8 +64,8 @@
✓ it has bar ✓ it has bar
PASS Tests\Features\PendingHigherOrderTests PASS Tests\Features\PendingHigherOrderTests
✓ get 'foo' → get 'bar' → assert true true ✓ get 'foo' → get 'bar' → assertTrue true
✓ get 'foo' → assert true true ✓ get 'foo' → assertTrue true
WARN Tests\Features\Skip WARN Tests\Features\Skip
✓ it do not skips ✓ it do not skips
@ -81,16 +81,16 @@
✓ higher order message test ✓ higher order message test
PASS Tests\Fixtures\DirectoryWithTests\ExampleTest PASS Tests\Fixtures\DirectoryWithTests\ExampleTest
✓ it example ✓ it example 1
PASS Tests\Fixtures\ExampleTest PASS Tests\Fixtures\ExampleTest
✓ it example ✓ it example 2
PASS Tests\PHPUnit\CustomTestCase\UsesPerDirectory PASS Tests\PHPUnit\CustomTestCase\UsesPerDirectory
✓ closure was bound to custom test case ✓ closure was bound to CustomTestCase
PASS Tests\PHPUnit\CustomTestCaseInSubFolders\SubFolder\SubFolder\UsesPerSubDirectory 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 PASS Tests\PHPUnit\CustomTestCaseInSubFolders\SubFolder2\UsesPerFile
✓ custom traits can be used ✓ custom traits can be used
@ -137,7 +137,7 @@
PASS Tests\Visual\SingleTestOrDirectory PASS Tests\Visual\SingleTestOrDirectory
✓ allows to run a single test ✓ allows to run a single test
✓ allows to run a directory ✓ 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 ✓ it disable decorating printer when colors is set to never
WARN Tests\Visual\Success WARN Tests\Visual\Success

View File

@ -1,3 +1,3 @@
<?php <?php
it('example')->assertTrue(true); it('example 1')->assertTrue(true);

View File

@ -1,3 +1,3 @@
<?php <?php
it('example')->assertTrue(true); it('example 2')->assertTrue(true);

View File

@ -7,7 +7,7 @@ namespace Tests\CustomTestCase;
use function PHPUnit\Framework\assertTrue; use function PHPUnit\Framework\assertTrue;
use PHPUnit\Framework\TestCase; use PHPUnit\Framework\TestCase;
class PhpunitTest extends TestCase class ExecutedTest extends TestCase
{ {
public static $executed = false; public static $executed = false;
@ -16,8 +16,8 @@ class PhpunitTest extends TestCase
{ {
self::$executed = true; self::$executed = true;
$this->assertTrue(true); assertTrue(true);
} }
} }
// register_shutdown_function(fn () => assertTrue(PhpunitTest::$executed)); // register_shutdown_function(fn () => assertTrue(ExecutedTest::$executed));

View File

@ -2,53 +2,47 @@
use Symfony\Component\Process\Process; use Symfony\Component\Process\Process;
$run = function (string $target) { $run = function (string $target, $decorated = false) {
$process = new Process(['./bin/pest', $target], dirname(__DIR__, 2)); $process = new Process(['php', 'bin/pest', $target], dirname(__DIR__, 2));
$process->run(); $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) { $snapshot = function ($name) {
assertStringContainsString(<<<EOF $testsPath = dirname(__DIR__);
PASS Tests\Fixtures\DirectoryWithTests\ExampleTest
it example
Tests: 1 passed return file_get_contents(implode(DIRECTORY_SEPARATOR, [
EOF, $run('tests/Fixtures/DirectoryWithTests/ExampleTest.php')); $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) { test('allows to run a directory', function () use ($run, $snapshot) {
assertStringContainsString(<<<EOF assertStringContainsString(
PASS Tests\Fixtures\DirectoryWithTests\ExampleTest $snapshot('allows-to-run-a-directory'),
it example $run('tests/Fixtures')
);
PASS Tests\Fixtures\ExampleTest
it example
Tests: 2 passed
EOF, $run('tests/Fixtures'));
}); });
it('has ascii chars (decorated printer)', function () { it('has ascii chars', function () use ($run, $snapshot) {
$process = new Process([ assertStringContainsString(
'./bin/pest', $snapshot('has-ascii-chars'),
'tests/Fixtures/DirectoryWithTests/ExampleTest.php', $run('tests/Fixtures/DirectoryWithTests/ExampleTest.php', true)
], dirname(__DIR__, 2)); );
});
$process->run();
$output = $process->getOutput(); it('disable decorating printer when colors is set to never', function () use ($snapshot) {
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 () {
$process = new Process([ $process = new Process([
'php',
'./bin/pest', './bin/pest',
'--colors=never', '--colors=never',
'tests/Fixtures/DirectoryWithTests/ExampleTest.php', 'tests/Fixtures/DirectoryWithTests/ExampleTest.php',
@ -56,10 +50,8 @@ it('disable decorating printer when colors is set to never', function () {
$process->run(); $process->run();
$output = $process->getOutput(); $output = $process->getOutput();
assertStringContainsString(<<<EOF assertStringContainsString(
PASS Tests\Fixtures\DirectoryWithTests\ExampleTest $snapshot('disable-decorating-printer'),
\e[2mit example\e[22m $output
);
Tests: 1 passed
EOF, $output);
}); });

View File

@ -9,7 +9,7 @@ test('visual snapshot of test suite on success', function () {
]); ]);
$output = function () use ($testsPath) { $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(); $process->run();
@ -24,4 +24,5 @@ test('visual snapshot of test suite on success', function () {
array_pop($output); array_pop($output);
assertStringContainsString(implode("\n", $output), file_get_contents($snapshot)); 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
View File

@ -0,0 +1,6 @@
 PASS  Tests\Fixtures\DirectoryWithTests\ExampleTest
✓ it example 1
Tests: 1 passed
Time: 0.04s