Compare commits

...

18 Commits

Author SHA1 Message Date
19e3d929b1 docs: updates changelog 2023-06-19 10:29:10 +01:00
25729f6262 release: v2.8.0 2023-06-19 09:43:57 +01:00
cbb6a58c8a feat: only exits of init 2023-06-18 11:52:51 +01:00
167c96965e chore: removes broken test 2023-06-17 20:52:19 +01:00
8db3238a1f chore: updates deps 2023-06-17 19:39:52 +01:00
cbd8cae83e tests: updates snapshots 2023-06-17 19:39:44 +01:00
3e03a87e02 Merge pull request #838 from huangdijia/patch-1
Add container registration for Kernel self
2023-06-17 19:36:22 +01:00
193dd107d7 Merge pull request #839 from cerbero90/feature/compact-output
[2.x] Compact output when using datasets
2023-06-17 19:35:35 +01:00
0cea8fe922 Merge pull request #829 from mozex/allow-pattern-in-uses
Update directory targeting logic to support glob patterns
2023-06-17 16:28:39 +01:00
abbbc9fdbb chore: update snapshot 2023-06-16 23:48:37 +02:00
10b210d2bb feat: compact console output by redacting object annotations 2023-06-16 23:48:20 +02:00
9385a3dcea Add container registration for Kernel self 2023-06-16 14:41:46 +08:00
801346b894 move tests to GlobPatternTests folder and add comments for test cases 2023-06-12 12:53:27 +03:00
40fd06c0d0 Update src/PendingCalls/UsesCall.php
Co-authored-by: Owen Voke <development@voke.dev>
2023-06-12 12:38:51 +03:00
aa9fe351a6 fix tests and static type check error 2023-06-10 18:00:46 +03:00
e00efb1b6d add tests for directory and file patterns 2023-06-08 14:52:39 +03:00
86a765b06b Merge branch 'pestphp:2.x' into allow-pattern-in-uses 2023-06-08 14:50:51 +03:00
c9180e590e Update directory targeting logic to support glob patterns 2023-06-07 14:56:19 +03:00
18 changed files with 74 additions and 126 deletions

View File

@ -2,6 +2,11 @@
## Unreleased ## Unreleased
## [v2.8.0 (2023-06-19)](https://github.com/pestphp/pest/compare/v2.7.0...v2.8.0)
### Added
- Support for `globs` in `uses` ([#829](https://github.com/pestphp/pest/pull/829))
## [v2.7.0 (2023-06-15)](https://github.com/pestphp/pest/compare/v2.6.3...v2.7.0) ## [v2.7.0 (2023-06-15)](https://github.com/pestphp/pest/compare/v2.6.3...v2.7.0)
### Added ### Added

View File

@ -22,7 +22,7 @@
"nunomaduro/collision": "^7.6.0", "nunomaduro/collision": "^7.6.0",
"nunomaduro/termwind": "^1.15.1", "nunomaduro/termwind": "^1.15.1",
"pestphp/pest-plugin": "^2.0.1", "pestphp/pest-plugin": "^2.0.1",
"pestphp/pest-plugin-arch": "^2.2.0", "pestphp/pest-plugin-arch": "^2.2.1",
"phpunit/phpunit": "^10.2.2" "phpunit/phpunit": "^10.2.2"
}, },
"conflict": { "conflict": {

View File

@ -67,10 +67,14 @@ final class Kernel
CallsBoot::execute(); CallsBoot::execute();
return new self( $kernel = new self(
new Application(), new Application(),
$output, $output,
); );
Container::getInstance()->add(self::class, $kernel);
return $kernel;
} }
/** /**

View File

@ -84,8 +84,10 @@ final class UsesCall
}, $targets); }, $targets);
$this->targets = array_reduce($targets, function (array $accumulator, string $target): array { $this->targets = array_reduce($targets, function (array $accumulator, string $target): array {
if (is_dir($target) || file_exists($target)) { if (($matches = glob($target)) !== false) {
$accumulator[] = (string) realpath($target); foreach ($matches as $file) {
$accumulator[] = (string) realpath($file);
}
} }
return $accumulator; return $accumulator;

View File

@ -6,7 +6,7 @@ namespace Pest;
function version(): string function version(): string
{ {
return '2.7.0'; return '2.8.0';
} }
function testDirectory(string $file = ''): string function testDirectory(string $file = ''): string

View File

@ -60,13 +60,13 @@ final class Init implements HandlesArguments
$this->init(); $this->init();
return array_values($arguments); exit(0);
} }
/** /**
* Initializes the tests directory. * Initializes the tests directory.
*/ */
private function init(): void public function init(): void
{ {
$testsBaseDir = "{$this->testSuite->rootPath}/tests"; $testsBaseDir = "{$this->testSuite->rootPath}/tests";
@ -112,8 +112,6 @@ final class Init implements HandlesArguments
View::render('components.new-line'); View::render('components.new-line');
(new Thanks($this->input, $this->output))(); (new Thanks($this->input, $this->output))();
exit(0);
} }
/** /**

View File

@ -77,6 +77,12 @@ final class Exporter
*/ */
public function shortenedExport(mixed $value): string public function shortenedExport(mixed $value): string
{ {
return (string) preg_replace(['#\.{3}#', '#\\\n\s*#'], ['…'], $this->exporter->shortenedExport($value)); $map = [
'#\.{3}#' => '…',
'#\\\n\s*#' => '',
'# Object \(…\)#' => '',
];
return (string) preg_replace(array_keys($map), array_values($map), $this->exporter->shortenedExport($value));
} }
} }

View File

@ -1,7 +1,7 @@
##teamcity[testSuiteStarted name='Tests/tests/Failure' locationHint='file://tests/.tests/Failure.php' flowId='1234'] ##teamcity[testSuiteStarted name='Tests/tests/Failure' locationHint='file://tests/.tests/Failure.php' flowId='1234']
##teamcity[testCount count='8' flowId='1234'] ##teamcity[testCount count='8' flowId='1234']
##teamcity[testStarted name='it can fail with comparison' locationHint='pest_qn://tests/.tests/Failure.php::it can fail with comparison' flowId='1234'] ##teamcity[testStarted name='it can fail with comparison' locationHint='pest_qn://tests/.tests/Failure.php::it can fail with comparison' flowId='1234']
##teamcity[testFailed name='it can fail with comparison' message='Failed asserting that true matches expected false.' details='at src/Mixins/Expectation.php:343|nat src/Support/ExpectationPipeline.php:75|nat src/Support/ExpectationPipeline.php:79|nat src/Expectation.php:300|nat tests/.tests/Failure.php:6|nat src/Factories/TestCaseMethodFactory.php:100|nat src/Concerns/Testable.php:302|nat src/Support/ExceptionTrace.php:28|nat src/Concerns/Testable.php:302|nat src/Concerns/Testable.php:221|nat src/Kernel.php:86' type='comparisonFailure' actual='true' expected='false' flowId='1234'] ##teamcity[testFailed name='it can fail with comparison' message='Failed asserting that true matches expected false.' details='at src/Mixins/Expectation.php:343|nat src/Support/ExpectationPipeline.php:75|nat src/Support/ExpectationPipeline.php:79|nat src/Expectation.php:300|nat tests/.tests/Failure.php:6|nat src/Factories/TestCaseMethodFactory.php:100|nat src/Concerns/Testable.php:302|nat src/Support/ExceptionTrace.php:28|nat src/Concerns/Testable.php:302|nat src/Concerns/Testable.php:221|nat src/Kernel.php:90' 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']
@ -10,10 +10,10 @@
##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: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[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:90' 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 throws exception' locationHint='pest_qn://tests/.tests/Failure.php::it throws exception' flowId='1234'] ##teamcity[testStarted name='it throws exception' locationHint='pest_qn://tests/.tests/Failure.php::it throws exception' flowId='1234']
##teamcity[testFailed name='it throws exception' message='Exception: test error' details='at tests/.tests/Failure.php:22|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[testFailed name='it throws exception' message='Exception: test error' details='at tests/.tests/Failure.php:22|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:90' flowId='1234']
##teamcity[testFinished name='it throws exception' duration='100000' flowId='1234'] ##teamcity[testFinished name='it throws exception' 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']

View File

@ -1,5 +1,5 @@
Pest Testing Framework 2.7.0. Pest Testing Framework 2.8.0.
USAGE: pest <file> [options] USAGE: pest <file> [options]

View File

@ -80,7 +80,7 @@
✓ named datasets with dataset "one" ✓ named datasets with dataset "one"
✓ named datasets with dataset "two" ✓ named datasets with dataset "two"
✓ named datasets did the job right ✓ named datasets did the job right
✓ lazy named datasets with (Bar Object (…)) ✓ lazy named datasets with (Bar)
✓ it creates unique test case names with ('Name 1', Pest\Plugin Object (), true) #1 ✓ it creates unique test case names with ('Name 1', Pest\Plugin Object (), true) #1
✓ it creates unique test case names with ('Name 1', Pest\Plugin Object (), true) #2 ✓ it creates unique test case names with ('Name 1', Pest\Plugin Object (), true) #2
✓ it creates unique test case names with ('Name 1', Pest\Plugin Object (), false) ✓ it creates unique test case names with ('Name 1', Pest\Plugin Object (), false)
@ -134,24 +134,24 @@
✓ eager registered wrapped datasets with Generator functions did the job right ✓ eager registered wrapped datasets with Generator functions did the job right
✓ eager registered wrapped datasets with Generator functions display description with dataset "taylor" ✓ eager registered wrapped datasets with Generator functions display description with dataset "taylor"
✓ eager registered wrapped datasets with Generator functions display description with dataset "james" ✓ eager registered wrapped datasets with Generator functions display description with dataset "james"
✓ it can resolve a dataset after the test case is available with (Closure Object (…)) #1 ✓ it can resolve a dataset after the test case is available with (Closure) #1
✓ it can resolve a dataset after the test case is available with (Closure Object (…)) #2 ✓ it can resolve a dataset after the test case is available with (Closure) #2
✓ it can resolve a dataset after the test case is available with multiple datasets with (Closure Object (…)) / (Closure Object (…)) #1 ✓ it can resolve a dataset after the test case is available with multiple datasets with (Closure) / (Closure) #1
✓ it can resolve a dataset after the test case is available with multiple datasets with (Closure Object (…)) / (Closure Object (…)) #2 ✓ it can resolve a dataset after the test case is available with multiple datasets with (Closure) / (Closure) #2
✓ it can resolve a dataset after the test case is available with multiple datasets with (Closure Object (…)) / (Closure Object (…)) #3 ✓ it can resolve a dataset after the test case is available with multiple datasets with (Closure) / (Closure) #3
✓ it can resolve a dataset after the test case is available with multiple datasets with (Closure Object (…)) / (Closure Object (…)) #4 ✓ it can resolve a dataset after the test case is available with multiple datasets with (Closure) / (Closure) #4
✓ it can resolve a dataset after the test case is available with shared yield sets with (Closure Object (…)) #1 ✓ it can resolve a dataset after the test case is available with shared yield sets with (Closure) #1
✓ it can resolve a dataset after the test case is available with shared yield sets with (Closure Object (…)) #2 ✓ it can resolve a dataset after the test case is available with shared yield sets with (Closure) #2
✓ it can resolve a dataset after the test case is available with shared array sets with (Closure Object (…)) #1 ✓ it can resolve a dataset after the test case is available with shared array sets with (Closure) #1
✓ it can resolve a dataset after the test case is available with shared array sets with (Closure Object (…)) #2 ✓ it can resolve a dataset after the test case is available with shared array sets with (Closure) #2
✓ it resolves a potential bound dataset logically with ('foo', Closure Object (…)) ✓ it resolves a potential bound dataset logically with ('foo', Closure)
✓ it resolves a potential bound dataset logically even when the closure comes first with (Closure Object (…), 'bar') ✓ it resolves a potential bound dataset logically even when the closure comes first with (Closure, 'bar')
✓ it will not resolve a closure if it is type hinted as a closure with (Closure Object (…)) #1 ✓ it will not resolve a closure if it is type hinted as a closure with (Closure) #1
✓ it will not resolve a closure if it is type hinted as a closure with (Closure Object (…)) #2 ✓ it will not resolve a closure if it is type hinted as a closure with (Closure) #2
✓ it will not resolve a closure if it is type hinted as a callable with (Closure Object (…)) #1 ✓ it will not resolve a closure if it is type hinted as a callable with (Closure) #1
✓ it will not resolve a closure if it is type hinted as a callable with (Closure Object (…)) #2 ✓ it will not resolve a closure if it is type hinted as a callable with (Closure) #2
✓ it can correctly resolve a bound dataset that returns an array with (Closure Object (…)) ✓ it can correctly resolve a bound dataset that returns an array with (Closure)
✓ it can correctly resolve a bound dataset that returns an array but wants to be spread with (Closure Object (…)) ✓ it can correctly resolve a bound dataset that returns an array but wants to be spread with (Closure)
↓ forbids to define tests in Datasets dirs and Datasets.php files ↓ forbids to define tests in Datasets dirs and Datasets.php files
PASS Tests\Features\Depends PASS Tests\Features\Depends
@ -586,7 +586,7 @@
✓ it passes with ('Fortaleza') ✓ it passes with ('Fortaleza')
✓ it passes with ('Sollefteå') ✓ it passes with ('Sollefteå')
✓ it passes with ('Ιεράπετρα') ✓ it passes with ('Ιεράπετρα')
✓ it passes with (stdClass Object (…)) ✓ it passes with (stdClass)
✓ it passes with array ✓ it passes with array
✓ it passes with *not* ✓ it passes with *not*
✓ it properly fails with *not* ✓ it properly fails with *not*
@ -866,6 +866,12 @@
✓ custom traits can be used ✓ custom traits can be used
✓ trait applied in this file ✓ trait applied in this file
PASS Tests\PHPUnit\GlobPatternTests\SubFolder\InnerFolder\UsesPerDirectoryAsPattern
✓ closure was bound to CustomTestCase
PASS Tests\PHPUnit\GlobPatternTests\SubFolder2\UsesPerFileAsPattern
✓ closure was bound to CustomTestCase
PASS Tests\Playground PASS Tests\Playground
✓ basic ✓ basic
@ -1038,10 +1044,6 @@
✓ todo ✓ todo
✓ todo in parallel ✓ todo in parallel
PASS Tests\Visual\UnexpectedOutput
✓ unexpected output with ([''])
✓ unexpected output with (['--parallel'])
PASS Tests\Visual\Version PASS Tests\Visual\Version
✓ visual snapshot of help command output ✓ visual snapshot of help command output

View File

@ -1,23 +0,0 @@
.this is unexpected output!
────────────────────────────────────────────────────────────────────────────
RISKY Tests\Fixtures\UnexpectedOutput > output
This test printed output: this is unexpected output
at src/Support/StateGenerator.php:58
54▕ foreach ($riskyEvents as $riskyEvent) {
55▕ $state->add(TestResult::fromPestParallelTestCase(
56▕ $riskyEvent->test(),
57▕ TestResult::RISKY,
➜ 58▕ ThrowableBuilder::from(new TestOutcome($riskyEvent->message()))
59▕ ));
60▕ }
61▕ }
62▕
1 src/Support/StateGenerator.php:58
+5 vendor frames
7 src/Plugins/Actions/CallsHandleArguments.php:29
Tests: 1 risky, 1 passed (2 assertions)

View File

@ -1,20 +0,0 @@
this is unexpected output
WARN Tests\Fixtures\UnexpectedOutput
! output → This test printed output: this is unexpected output
────────────────────────────────────────────────────────────────────────────
RISKY Tests\Fixtures\UnexpectedOutput > output
This test printed output: this is unexpected output
at src/Kernel.php:86
82▕ {
83▕ $args = CallsHandleArguments::execute($args);
84▕
85▕ try {
➜ 86▕ $this->application->run($args);
87▕ } catch (NoDirtyTestsFound) {
88▕ $this->output->writeln([
89▕ '',
90▕ ' INFO No tests found.',
Tests: 1 risky (1 assertions)

View File

@ -1,3 +1,3 @@
Pest Testing Framework 2.7.0. Pest Testing Framework 2.8.0.

View File

@ -0,0 +1,5 @@
<?php
test('closure was bound to CustomTestCase', function () {
$this->assertCustomTrue();
});

View File

@ -0,0 +1,5 @@
<?php
test('closure was bound to CustomTestCase', function () {
$this->assertCustomTrue();
});

View File

@ -1,9 +1,16 @@
<?php <?php
use Tests\CustomTestCase\CustomTestCase;
use Tests\CustomTestCaseInSubFolders\SubFolder\SubFolder\CustomTestCaseInSubFolder; use Tests\CustomTestCaseInSubFolders\SubFolder\SubFolder\CustomTestCaseInSubFolder;
uses(CustomTestCaseInSubFolder::class)->in('PHPUnit/CustomTestCaseInSubFolders/SubFolder/SubFolder'); uses(CustomTestCaseInSubFolder::class)->in('PHPUnit/CustomTestCaseInSubFolders/SubFolder/SubFolder');
// test case for all the directories inside PHPUnit/GlobPatternTests/SubFolder/
uses(CustomTestCase::class)->in('PHPUnit/GlobPatternTests/SubFolder/*/');
// test case for all the files that end with AsPattern.php inside PHPUnit/GlobPatternTests/SubFolder2/
uses(CustomTestCase::class)->in('PHPUnit/GlobPatternTests/SubFolder2/*AsPattern.php');
uses()->group('integration')->in('Visual'); uses()->group('integration')->in('Visual');
// 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

View File

@ -18,7 +18,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: 1 deprecated, 3 warnings, 4 incomplete, 1 notice, 8 todos, 15 skipped, 705 passed (1718 assertions)') ->toContain('Tests: 1 deprecated, 3 warnings, 4 incomplete, 1 notice, 8 todos, 15 skipped, 707 passed (1720 assertions)')
->toContain('Parallel: 3 processes'); ->toContain('Parallel: 3 processes');
})->skipOnWindows(); })->skipOnWindows();

View File

@ -1,43 +0,0 @@
<?php
test('unexpected output', function (array $arguments) {
$snapshot = __DIR__.'/../.snapshots/unexpected-output.txt';
if (in_array('--parallel', $arguments)) {
$snapshot = __DIR__.'/../.snapshots/unexpected-output-parallel.txt';
}
$output = function () use ($arguments) {
$process = (new Symfony\Component\Process\Process(
array_merge(['php', 'bin/pest', 'tests/Fixtures/UnexpectedOutput.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']],
])->skipOnWindows();