mirror of
https://github.com/pestphp/pest.git
synced 2026-03-06 15:57:21 +01:00
Compare commits
20 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 66f69617f1 | |||
| 5721e8c29a | |||
| 546d19fd84 | |||
| c1b32b9ffb | |||
| 298b1e6784 | |||
| 63f009fadf | |||
| 1066c2270d | |||
| 984f237a92 | |||
| dccd8239dd | |||
| e103623ecb | |||
| 542fc046d2 | |||
| 4720e0655b | |||
| a533772fe2 | |||
| 2218a0c137 | |||
| 2831629f1b | |||
| 1b7f1dc5b3 | |||
| 92b8d32ef7 | |||
| 2969c7a5e3 | |||
| 63c1faa9f4 | |||
| b5b14ef280 |
4
.github/workflows/changelog.yml
vendored
4
.github/workflows/changelog.yml
vendored
@ -2,12 +2,12 @@ name: Changelog
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [ master ]
|
||||
branches: [ 1.x ]
|
||||
paths:
|
||||
- CHANGELOG.md
|
||||
- .github/workflows/changelog.yml
|
||||
pull_request:
|
||||
branches: [ master ]
|
||||
branches: [ 1.x ]
|
||||
paths:
|
||||
- CHANGELOG.md
|
||||
jobs:
|
||||
|
||||
12
CHANGELOG.md
12
CHANGELOG.md
@ -4,6 +4,18 @@ All notable changes to this project will be documented in this file.
|
||||
The format is based on [Keep a Changelog](http://keepachangelog.com/)
|
||||
and this project adheres to [Semantic Versioning](http://semver.org/).
|
||||
|
||||
## [v1.21.3 (2022-05-12)](https://github.com/pestphp/pest/compare/v1.21.2...v1.21.3)
|
||||
### Fixed
|
||||
- Debug of high order tests ([c1b32b9](https://github.com/pestphp/pest/commit/c1b32b9ffb5134803c490592454b11b8c05ea27d))
|
||||
|
||||
## [v1.21.2 (2022-03-05)](https://github.com/pestphp/pest/compare/v1.21.1...v1.21.2)
|
||||
### Fixed
|
||||
- `toThrow` expectation when exception does not exist ([#487](https://github.com/pestphp/pest/pull/487))
|
||||
|
||||
## [v1.21.1 (2021-11-25)](https://github.com/pestphp/pest/compare/v1.21.0...v1.21.1)
|
||||
### Fixed
|
||||
- sequence callables causing problems ([#442](https://github.com/pestphp/pest/pull/442))
|
||||
|
||||
## [v1.21.0 (2021-11-17)](https://github.com/pestphp/pest/compare/v1.20.0...v1.21.0)
|
||||
### Added
|
||||
- warn about xdebug modes ([1e011c](https://github.com/pestphp/pest/commit/1e011c7b4074d08f5dabab1f927d45383c85d210))
|
||||
|
||||
@ -2,8 +2,8 @@
|
||||
|
||||
When releasing a new version of Pest there are some checks and updates that need to be done:
|
||||
|
||||
- Clear your local repository with: `git add . && git reset --hard && git checkout master`
|
||||
- On the GitHub repository, check the contents of [github.com/pestphp/pest/compare/{latest_version}...master](https://github.com/pestphp/pest/compare/{latest_version}...master) and update the [changelog](CHANGELOG.md) file with the main changes for this release
|
||||
- Clear your local repository with: `git add . && git reset --hard && git checkout 1.x`
|
||||
- On the GitHub repository, check the contents of [github.com/pestphp/pest/compare/{latest_version}...1.x](https://github.com/pestphp/pest/compare/{latest_version}...1.x) and update the [changelog](CHANGELOG.md) file with the main changes for this release
|
||||
- Update the version number in [src/Pest.php](src/Pest.php)
|
||||
- Run the tests locally using: `composer test`
|
||||
- Commit the CHANGELOG and Pest file with the message: `git commit -m "release: vX.X.X"`
|
||||
|
||||
@ -18,7 +18,7 @@
|
||||
],
|
||||
"require": {
|
||||
"php": "^7.3 || ^8.0",
|
||||
"nunomaduro/collision": "^5.4.0|^6.0",
|
||||
"nunomaduro/collision": "^5.10.0|^6.0",
|
||||
"pestphp/pest-plugin": "^1.0.0",
|
||||
"phpunit/phpunit": "^9.5.5"
|
||||
},
|
||||
@ -50,7 +50,10 @@
|
||||
"prefer-stable": true,
|
||||
"config": {
|
||||
"sort-packages": true,
|
||||
"preferred-install": "dist"
|
||||
"preferred-install": "dist",
|
||||
"allow-plugins": {
|
||||
"pestphp/pest-plugin": true
|
||||
}
|
||||
},
|
||||
"bin": [
|
||||
"bin/pest"
|
||||
@ -73,7 +76,7 @@
|
||||
},
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "1.x-dev"
|
||||
"dev-1.x": "1.x-dev"
|
||||
},
|
||||
"pest": {
|
||||
"plugins": [
|
||||
|
||||
@ -140,11 +140,6 @@ parameters:
|
||||
count: 2
|
||||
path: src/Expectation.php
|
||||
|
||||
-
|
||||
message: "#^Parameter \\#1 \\$value of method Pest\\\\Expectation\\<TValue\\>\\:\\:and\\(\\) expects TValue, mixed given\\.$#"
|
||||
count: 2
|
||||
path: src/Expectation.php
|
||||
|
||||
-
|
||||
message: "#^Parameter \\#2 \\$haystack of static method PHPUnit\\\\Framework\\\\Assert\\:\\:assertContains\\(\\) expects iterable, mixed given\\.$#"
|
||||
count: 1
|
||||
|
||||
@ -50,6 +50,7 @@ final class LoadStructure
|
||||
$directory = new RecursiveDirectoryIterator($filename);
|
||||
$iterator = new RecursiveIteratorIterator($directory);
|
||||
foreach ($iterator as $file) {
|
||||
/* @phpstan-ignore-next-line */
|
||||
$filename = $file->__toString();
|
||||
if (Str::endsWith($filename, '.php') && file_exists($filename)) {
|
||||
require_once $filename;
|
||||
|
||||
@ -6,6 +6,7 @@ namespace Pest;
|
||||
|
||||
use BadMethodCallException;
|
||||
use Closure;
|
||||
use Error;
|
||||
use InvalidArgumentException;
|
||||
use Pest\Concerns\Extendable;
|
||||
use Pest\Concerns\RetrievesValues;
|
||||
@ -170,7 +171,7 @@ final class Expectation
|
||||
}
|
||||
|
||||
foreach ($values as $key => $item) {
|
||||
if (is_callable($callbacks[$key])) {
|
||||
if ($callbacks[$key] instanceof Closure) {
|
||||
call_user_func($callbacks[$key], new self($item), new self($keys[$key]));
|
||||
continue;
|
||||
}
|
||||
@ -722,7 +723,7 @@ final class Expectation
|
||||
try {
|
||||
Assert::assertTrue(Arr::has($array, $key));
|
||||
|
||||
/* @phpstan-ignore-next-line */
|
||||
/* @phpstan-ignore-next-line */
|
||||
} catch (ExpectationFailedException $exception) {
|
||||
throw new ExpectationFailedException("Failed asserting that an array has the key '$key'", $exception->getComparisonFailure());
|
||||
}
|
||||
@ -911,8 +912,12 @@ final class Expectation
|
||||
|
||||
try {
|
||||
($this->value)();
|
||||
} catch (Throwable $e) { // @phpstan-ignore-line
|
||||
} catch (Throwable $e) {
|
||||
if (!class_exists($exception)) {
|
||||
if ($e instanceof Error && (bool) preg_match("/Class [\"']{$exception}[\"'] not found/", $e->getMessage())) {
|
||||
throw $e;
|
||||
}
|
||||
|
||||
Assert::assertStringContainsString($exception, $e->getMessage());
|
||||
|
||||
return $this;
|
||||
|
||||
@ -173,7 +173,6 @@ final class JUnit extends Printer implements TestListener
|
||||
$this->doAddSkipped();
|
||||
}
|
||||
|
||||
/** @phpstan-ignore-next-line */
|
||||
public function startTestSuite(TestSuite $suite): void
|
||||
{
|
||||
$testSuite = $this->document->createElement('testsuite');
|
||||
@ -212,7 +211,6 @@ final class JUnit extends Printer implements TestListener
|
||||
$this->testSuiteTimes[$this->testSuiteLevel] = 0;
|
||||
}
|
||||
|
||||
/** @phpstan-ignore-next-line */
|
||||
public function endTestSuite(TestSuite $suite): void
|
||||
{
|
||||
$this->testSuites[$this->testSuiteLevel]->setAttribute(
|
||||
|
||||
@ -106,7 +106,6 @@ final class TeamCity extends DefaultResultPrinter
|
||||
- $result->riskyCount();
|
||||
}
|
||||
|
||||
/** @phpstan-ignore-next-line */
|
||||
public function startTestSuite(TestSuite $suite): void
|
||||
{
|
||||
$suiteName = $suite->getName();
|
||||
@ -164,7 +163,6 @@ final class TeamCity extends DefaultResultPrinter
|
||||
);
|
||||
}
|
||||
|
||||
/** @phpstan-ignore-next-line */
|
||||
public function endTestSuite(TestSuite $suite): void
|
||||
{
|
||||
$suiteName = $suite->getName();
|
||||
|
||||
@ -183,7 +183,7 @@ final class TestCall
|
||||
*/
|
||||
public function __get(string $name): self
|
||||
{
|
||||
return $this->addChain($name);
|
||||
return $this->addChain(Backtrace::file(), Backtrace::line(), $name);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -193,7 +193,7 @@ final class TestCall
|
||||
*/
|
||||
public function __call(string $name, array $arguments): self
|
||||
{
|
||||
return $this->addChain($name, $arguments);
|
||||
return $this->addChain(Backtrace::file(), Backtrace::line(), $name, $arguments);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -201,11 +201,11 @@ final class TestCall
|
||||
*
|
||||
* @param array<int, mixed>|null $arguments
|
||||
*/
|
||||
private function addChain(string $name, array $arguments = null): self
|
||||
private function addChain(string $file, int $line, string $name, array $arguments = null): self
|
||||
{
|
||||
$this->testCaseFactory
|
||||
->chains
|
||||
->add(Backtrace::file(), Backtrace::line(), $name, $arguments);
|
||||
->add($file, $line, $name, $arguments);
|
||||
|
||||
if ($this->descriptionLess) {
|
||||
$exporter = new Exporter();
|
||||
|
||||
@ -6,7 +6,7 @@ namespace Pest;
|
||||
|
||||
function version(): string
|
||||
{
|
||||
return '1.21.0';
|
||||
return '1.21.3';
|
||||
}
|
||||
|
||||
function testDirectory(string $file = ''): string
|
||||
|
||||
@ -26,6 +26,7 @@ final class Backtrace
|
||||
$current = null;
|
||||
|
||||
foreach (debug_backtrace(self::BACKTRACE_OPTIONS) as $trace) {
|
||||
assert(array_key_exists(self::FILE, $trace));
|
||||
if (Str::endsWith($trace[self::FILE], (string) realpath('vendor/phpunit/phpunit/src/Util/FileLoader.php'))) {
|
||||
break;
|
||||
}
|
||||
@ -45,7 +46,11 @@ final class Backtrace
|
||||
*/
|
||||
public static function file(): string
|
||||
{
|
||||
return debug_backtrace(self::BACKTRACE_OPTIONS)[1][self::FILE];
|
||||
$trace = debug_backtrace(self::BACKTRACE_OPTIONS)[1];
|
||||
|
||||
assert(array_key_exists(self::FILE, $trace));
|
||||
|
||||
return $trace[self::FILE];
|
||||
}
|
||||
|
||||
/**
|
||||
@ -53,7 +58,11 @@ final class Backtrace
|
||||
*/
|
||||
public static function dirname(): string
|
||||
{
|
||||
return dirname(debug_backtrace(self::BACKTRACE_OPTIONS)[1][self::FILE]);
|
||||
$trace = debug_backtrace(self::BACKTRACE_OPTIONS)[1];
|
||||
|
||||
assert(array_key_exists(self::FILE, $trace));
|
||||
|
||||
return dirname($trace[self::FILE]);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -61,6 +70,10 @@ final class Backtrace
|
||||
*/
|
||||
public static function line(): int
|
||||
{
|
||||
return debug_backtrace(self::BACKTRACE_OPTIONS)[1]['line'];
|
||||
$trace = debug_backtrace(self::BACKTRACE_OPTIONS)[1];
|
||||
|
||||
assert(array_key_exists('line', $trace));
|
||||
|
||||
return $trace['line'];
|
||||
}
|
||||
}
|
||||
|
||||
@ -496,6 +496,8 @@
|
||||
✓ not failures
|
||||
✓ closure missing parameter
|
||||
✓ closure missing type-hint
|
||||
✓ it can handle a non-defined exception
|
||||
✓ it can handle a class not found Error
|
||||
|
||||
PASS Tests\Features\Expect\unless
|
||||
✓ it pass
|
||||
@ -720,5 +722,5 @@
|
||||
✓ it is a test
|
||||
✓ it uses correct parent class
|
||||
|
||||
Tests: 4 incompleted, 9 skipped, 478 passed
|
||||
Tests: 4 incompleted, 9 skipped, 480 passed
|
||||
|
||||
@ -8,7 +8,7 @@ use Symfony\Component\Console\Output\ConsoleOutput;
|
||||
it('has plugin')->assertTrue(class_exists(CoveragePlugin::class));
|
||||
|
||||
it('adds coverage if --coverage exist', function () {
|
||||
$plugin = new CoveragePlugin(new ConsoleOutput());
|
||||
$plugin = new CoveragePlugin(new ConsoleOutput());
|
||||
$testSuite = TestSuite::getInstance();
|
||||
|
||||
expect($plugin->coverage)->toBeFalse();
|
||||
|
||||
@ -5,7 +5,7 @@ use PHPUnit\Framework\ExpectationFailedException;
|
||||
expect(true)->toBeTrue()->and(false)->toBeFalse();
|
||||
|
||||
test('strict comparisons', function () {
|
||||
$nuno = new stdClass();
|
||||
$nuno = new stdClass();
|
||||
$dries = new stdClass();
|
||||
|
||||
expect($nuno)->toBe($nuno)->not->toBe($dries);
|
||||
|
||||
@ -3,24 +3,24 @@
|
||||
use PHPUnit\Framework\ExpectationFailedException;
|
||||
|
||||
test('pass', function () {
|
||||
$object = new stdClass();
|
||||
$object = new stdClass();
|
||||
$object->name = 'Jhon';
|
||||
$object->age = 21;
|
||||
$object->age = 21;
|
||||
|
||||
expect($object)->toHaveProperties(['name', 'age']);
|
||||
});
|
||||
|
||||
test('failures', function () {
|
||||
$object = new stdClass();
|
||||
$object = new stdClass();
|
||||
$object->name = 'Jhon';
|
||||
|
||||
expect($object)->toHaveProperties(['name', 'age']);
|
||||
})->throws(ExpectationFailedException::class);
|
||||
|
||||
test('not failures', function () {
|
||||
$object = new stdClass();
|
||||
$object = new stdClass();
|
||||
$object->name = 'Jhon';
|
||||
$object->age = 21;
|
||||
$object->age = 21;
|
||||
|
||||
expect($object)->not->toHaveProperties(['name', 'age']);
|
||||
})->throws(ExpectationFailedException::class);
|
||||
|
||||
@ -58,3 +58,15 @@ test('closure missing parameter', function () {
|
||||
test('closure missing type-hint', function () {
|
||||
expect(function () {})->toThrow(function ($e) {});
|
||||
})->throws(InvalidArgumentException::class, 'The given closure\'s parameter must be type-hinted as the class string.');
|
||||
|
||||
it('can handle a non-defined exception', function () {
|
||||
expect(function () {
|
||||
throw new NonExistingException();
|
||||
})->toThrow(NonExistingException::class);
|
||||
})->throws(Error::class);
|
||||
|
||||
it('can handle a class not found Error', function () {
|
||||
expect(function () {
|
||||
throw new NonExistingException();
|
||||
})->toThrow(Error::class);
|
||||
});
|
||||
|
||||
@ -3,9 +3,9 @@
|
||||
use PHPUnit\Framework\ExpectationFailedException;
|
||||
|
||||
beforeEach(function () {
|
||||
$this->unlessObject = new stdClass();
|
||||
$this->unlessObject = new stdClass();
|
||||
$this->unlessObject->trueValue = true;
|
||||
$this->unlessObject->foo = 'foo';
|
||||
$this->unlessObject->foo = 'foo';
|
||||
});
|
||||
|
||||
it('pass', function () {
|
||||
|
||||
@ -3,9 +3,9 @@
|
||||
use PHPUnit\Framework\ExpectationFailedException;
|
||||
|
||||
beforeEach(function () {
|
||||
$this->whenObject = new stdClass();
|
||||
$this->whenObject = new stdClass();
|
||||
$this->whenObject->trueValue = true;
|
||||
$this->whenObject->foo = 'foo';
|
||||
$this->whenObject->foo = 'foo';
|
||||
});
|
||||
|
||||
it('pass', function () {
|
||||
|
||||
@ -23,7 +23,7 @@ test('default php unit tests', function () {
|
||||
});
|
||||
|
||||
it('removes warnings', function () {
|
||||
$testSuite = new TestSuite();
|
||||
$testSuite = new TestSuite();
|
||||
$warningTestCase = new WarningTestCase('No tests found in class "Pest\TestCase".');
|
||||
$testSuite->addTest($warningTestCase);
|
||||
|
||||
|
||||
@ -10,7 +10,7 @@ it('gets file name from closure', function () {
|
||||
});
|
||||
|
||||
it('gets property values', function () {
|
||||
$class = new class() {
|
||||
$class = new class() {
|
||||
private $foo = 'bar';
|
||||
};
|
||||
|
||||
|
||||
@ -8,7 +8,7 @@ use Pest\TestSuite;
|
||||
|
||||
it('does not allow to add the same test description twice', function () {
|
||||
$testSuite = new TestSuite(getcwd(), 'tests');
|
||||
$test = function () {};
|
||||
$test = function () {};
|
||||
$testSuite->tests->set(new TestCaseFactory(__FILE__, 'foo', $test));
|
||||
$testSuite->tests->set(new TestCaseFactory(__FILE__, 'foo', $test));
|
||||
})->throws(
|
||||
@ -18,7 +18,7 @@ it('does not allow to add the same test description twice', function () {
|
||||
|
||||
it('alerts users about tests with arguments but no input', function () {
|
||||
$testSuite = new TestSuite(getcwd(), 'tests');
|
||||
$test = function (int $arg) {};
|
||||
$test = function (int $arg) {};
|
||||
$testSuite->tests->set(new TestCaseFactory(__FILE__, 'foo', $test));
|
||||
})->throws(
|
||||
DatasetMissing::class,
|
||||
@ -27,7 +27,7 @@ it('alerts users about tests with arguments but no input', function () {
|
||||
|
||||
it('can return an array of all test suite filenames', function () {
|
||||
$testSuite = TestSuite::getInstance(getcwd(), 'tests');
|
||||
$test = function () {};
|
||||
$test = function () {};
|
||||
$testSuite->tests->set(new TestCaseFactory(__FILE__, 'foo', $test));
|
||||
$testSuite->tests->set(new TestCaseFactory(__FILE__, 'bar', $test));
|
||||
|
||||
@ -39,9 +39,9 @@ it('can return an array of all test suite filenames', function () {
|
||||
|
||||
it('can filter the test suite filenames to those with the only method', function () {
|
||||
$testSuite = new TestSuite(getcwd(), 'tests');
|
||||
$test = function () {};
|
||||
$test = function () {};
|
||||
|
||||
$testWithOnly = new TestCaseFactory(__FILE__, 'foo', $test);
|
||||
$testWithOnly = new TestCaseFactory(__FILE__, 'foo', $test);
|
||||
$testWithOnly->only = true;
|
||||
$testSuite->tests->set($testWithOnly);
|
||||
|
||||
@ -59,7 +59,7 @@ it('does not filter the test suite filenames to those with the only method when
|
||||
|
||||
$test = function () {};
|
||||
|
||||
$testWithOnly = new TestCaseFactory(__FILE__, 'foo', $test);
|
||||
$testWithOnly = new TestCaseFactory(__FILE__, 'foo', $test);
|
||||
$testWithOnly->only = true;
|
||||
$testSuite->tests->set($testWithOnly);
|
||||
|
||||
|
||||
@ -8,7 +8,7 @@ test('visual snapshot of help command output', function () {
|
||||
|
||||
if (getenv('REBUILD_SNAPSHOTS')) {
|
||||
$outputBuffer = new BufferedOutput();
|
||||
$plugin = new Help($outputBuffer);
|
||||
$plugin = new Help($outputBuffer);
|
||||
|
||||
$plugin();
|
||||
|
||||
|
||||
@ -2,7 +2,7 @@
|
||||
|
||||
test('visual snapshot of test suite on success', function () {
|
||||
$testsPath = dirname(__DIR__);
|
||||
$snapshot = implode(DIRECTORY_SEPARATOR, [
|
||||
$snapshot = implode(DIRECTORY_SEPARATOR, [
|
||||
$testsPath,
|
||||
'.snapshots',
|
||||
'success.txt',
|
||||
|
||||
Reference in New Issue
Block a user