Compare commits

...

20 Commits

Author SHA1 Message Date
23eebc8127 docs: updates changelog 2020-12-04 21:19:40 +01:00
3b435e460e chore: increases version 2020-12-04 21:19:32 +01:00
b52e9826e7 Merge pull request #234 from soilSpoon/feature/phpunit
Update PHPUnit dependency version
2020-12-04 09:16:27 +01:00
ba49dd0499 Update PHPUnit dependency version 2020-12-04 15:46:25 +09:00
f9f6f28950 Merge pull request #233 from misaert/feat-authorize-associative-array-for-with
fix: authorize string as key for datasets
2020-11-30 16:42:35 +01:00
f017015d1e fix: authorize string as key for datasets 2020-11-30 14:50:40 +01:00
29b4ee33bb Merge pull request #232 from pestphp/feat/expect-extend
feat: makes expect extendable
2020-11-29 18:25:21 +01:00
03dc11c2f6 Adds expect extend 2020-11-29 16:30:57 +01:00
b79ba5098b docs: updates changelog 2020-11-28 18:55:22 +01:00
3c418d82e6 chore: increases version 2020-11-28 18:55:14 +01:00
73ede2e344 Merge pull request #223 from clmntgr/support-pest-command
Add a dusk command for Laravel
2020-11-28 18:46:51 +01:00
266d891488 Merge pull request #231 from pestphp/feat/feedback-on-to-match
feat: adds key/value context when toMatchObject or toMatchArray fails
2020-11-28 18:21:52 +01:00
c71490b472 feat(feedback-on-to-match): uses contextual messages inside expectations 2020-11-27 21:52:44 +01:00
07705079e2 Merge pull request #229 from owenvoke/feature/release-guide
docs: add release guide
2020-11-27 11:42:46 +01:00
d88c268426 docs: use docs prefix in release commit message 2020-11-27 09:13:38 +00:00
a1b142e885 docs: add details on plugin versioning 2020-11-26 19:55:42 +00:00
a50d739e50 docs: add release guide 2020-11-26 19:55:11 +00:00
f82bb56d89 chore: update changelog 2020-11-24 09:12:43 +00:00
de593c3b93 Add a dusk command for Laravel.
This new command will replicate Dusk behavior with .env.dusk files
2020-11-24 10:07:06 +01:00
eedd5d80a0 chore: updates version 2020-11-23 22:01:06 +01:00
15 changed files with 277 additions and 11 deletions

View File

@ -4,9 +4,26 @@ 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/).
## [v0.3.15 (2020-12-04)](https://github.com/pestphp/pest/compare/v0.3.14...v0.3.15)
### Added
- Support for PHPUnit 9.5.0 ([#234](https://github.com/pestphp/pest/pull/234))
- Support for extending expectation API ([#232](https://github.com/pestphp/pest/pull/232))
### Fixed
- Static analysis while using string as key for datasets ([#233](https://github.com/pestphp/pest/pull/233))
## [v0.3.14 (2020-11-28)](https://github.com/pestphp/pest/compare/v0.3.13...v0.3.14)
### Added
- `pest:dusk` command ([#223](https://github.com/pestphp/pest/pull/223))
- Better feedback on errors in `toMatchArray` and `toMatchObject` ([#231](https://github.com/pestphp/pest/pull/231))
## [v0.3.13 (2020-11-23)](https://github.com/pestphp/pest/compare/v0.3.12...v0.3.13)
### Added
- `toMatchArray` expectation ([7bea51f](https://github.com/pestphp/pest/commit/7bea51fe09dd2eca7093e4c34cf2dab2e8d39fa5), [3fd24d9](https://github.com/pestphp/pest/commit/3fd24d96d3145dcebdb0aab40aa8b76faa8b6979))
- Add Pest options to `--help` output ([#217](https://github.com/pestphp/pest/pull/217))
### Fixed
- Resolve issue with name resolution in `depends()` ([#216](https://github.com/pestphp/pest/pull/216))
## [v0.3.12 (2020-11-11)](https://github.com/pestphp/pest/compare/v0.3.11...v0.3.12)
### Added

16
RELEASE.md Normal file
View File

@ -0,0 +1,16 @@
# Release process
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
- 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 "docs: update changelog"`
- Push the changes to GitHub
- Check that the CI is passing as expected: [github.com/pestphp/pest/actions](https://github.com/pestphp/pest/actions)
- Tag and push the tag with `git tag vX.X.X && git push --tags`
### Plugins
Plugins should be versioned using the same major (or minor for `0.x` releases) version as Pest core.

View File

@ -22,7 +22,7 @@
"pestphp/pest-plugin": "^0.3",
"pestphp/pest-plugin-coverage": "^0.3",
"pestphp/pest-plugin-init": "^0.3",
"phpunit/phpunit": ">= 9.3.7 <= 9.4.3"
"phpunit/phpunit": ">= 9.3.7 <= 9.5.0"
},
"autoload": {
"psr-4": {
@ -44,6 +44,7 @@
"require-dev": {
"illuminate/console": "^7.16.1",
"illuminate/support": "^7.16.1",
"laravel/dusk": "^6.9.0",
"mockery/mockery": "^1.4.1",
"pestphp/pest-dev-tools": "dev-master"
},

View File

@ -0,0 +1,55 @@
<?php
declare(strict_types=1);
namespace Pest\Concerns;
use BadMethodCallException;
use Closure;
/**
* @internal
*/
trait Extendable
{
/**
* @var array<string, Closure>
*/
private static $extends = [];
/**
* Register a custom extend.
*/
public static function extend(string $name, Closure $extend): void
{
static::$extends[$name] = $extend;
}
/**
* Checks if extend is registered.
*/
public static function hasExtend(string $name): bool
{
return array_key_exists($name, static::$extends);
}
/**
* Dynamically handle calls to the class.
*
* @param array<int, mixed> $parameters
*
* @return mixed
*
* @throws BadMethodCallException
*/
public function __call(string $method, array $parameters)
{
if (!static::hasExtend($method)) {
throw new BadMethodCallException(sprintf('Method %s::%s does not exist.', static::class, $method));
}
$extend = static::$extends[$method]->bindTo($this, static::class);
return $extend(...$parameters);
}
}

View File

@ -51,7 +51,7 @@ final class Datasets
/**
* Resolves the current dataset to an array value.
*
* @param Traversable<int, mixed>|Closure|iterable<int, mixed>|string|null $data
* @param Traversable<int|string, mixed>|Closure|iterable<int|string, mixed>|string|null $data
*
* @return array<string, mixed>
*/

View File

@ -4,8 +4,10 @@ declare(strict_types=1);
namespace Pest;
use Pest\Concerns\Extendable;
use PHPUnit\Framework\Assert;
use PHPUnit\Framework\Constraint\Constraint;
use SebastianBergmann\Exporter\Exporter;
/**
* @internal
@ -14,6 +16,8 @@ use PHPUnit\Framework\Constraint\Constraint;
*/
final class Expectation
{
use Extendable;
/**
* The expectation value.
*
@ -23,6 +27,15 @@ final class Expectation
*/
public $value;
/**
* The exporter instance, if any.
*
* @readonly
*
* @var Exporter|null
*/
private $exporter;
/**
* Creates a new expectation.
*
@ -508,8 +521,24 @@ final class Expectation
*/
public function toMatchArray($array): Expectation
{
foreach ($array as $property => $value) {
$this->toHaveKey($property, $value);
if (is_object($this->value) && method_exists($this->value, 'toArray')) {
$valueAsArray = $this->value->toArray();
} else {
$valueAsArray = (array) $this->value;
}
foreach ($array as $key => $value) {
Assert::assertArrayHasKey($key, $valueAsArray);
Assert::assertEquals(
$value,
$valueAsArray[$key],
sprintf(
'Failed asserting that an array has a key %s with the value %s.',
$this->export($key),
$this->export($valueAsArray[$key]),
),
);
}
return $this;
@ -524,7 +553,19 @@ final class Expectation
public function toMatchObject($object): Expectation
{
foreach ((array) $object as $property => $value) {
$this->toHaveProperty($property, $value);
Assert::assertTrue(property_exists($this->value, $property));
/* @phpstan-ignore-next-line */
$propertyValue = $this->value->{$property};
Assert::assertEquals(
$value,
$propertyValue,
sprintf(
'Failed asserting that an object has a property %s with the value %s.',
$this->export($property),
$this->export($propertyValue),
),
);
}
return $this;
@ -550,6 +591,20 @@ final class Expectation
return $this;
}
/**
* Exports the given value.
*
* @param mixed $value
*/
private function export($value): string
{
if ($this->exporter === null) {
$this->exporter = new Exporter();
}
return $this->exporter->export($value);
}
/**
* Dynamically calls methods on the class without any arguments.
*

View File

@ -59,7 +59,7 @@ final class TestCaseFactory
/**
* Holds the dataset, if any.
*
* @var Closure|iterable<int, mixed>|string|null
* @var Closure|iterable<int|string, mixed>|string|null
*/
public $dataset;

View File

@ -0,0 +1,41 @@
<?php
declare(strict_types=1);
namespace Pest\Laravel\Commands;
use Laravel\Dusk\Console\DuskCommand;
/**
* @internal
*/
final class PestDuskCommand extends DuskCommand
{
/**
* The console command name.
*
* @var string
*/
protected $signature = 'pest:dusk {--without-tty : Disable output to TTY}';
/**
* The console command description.
*
* @var string
*/
protected $description = 'Run the Dusk tests for the application with Pest';
/**
* Get the PHP binary to execute.
*
* @return array<string>
*/
protected function binary()
{
if ('phpdbg' === PHP_SAPI) {
return [PHP_BINARY, '-qrr', 'vendor/bin/pest'];
}
return [PHP_BINARY, 'vendor/bin/pest'];
}
}

View File

@ -5,7 +5,9 @@ declare(strict_types=1);
namespace Pest\Laravel;
use Illuminate\Support\ServiceProvider;
use Laravel\Dusk\Console\DuskCommand;
use Pest\Laravel\Commands\PestDatasetCommand;
use Pest\Laravel\Commands\PestDuskCommand;
use Pest\Laravel\Commands\PestInstallCommand;
use Pest\Laravel\Commands\PestTestCommand;
@ -22,6 +24,12 @@ final class PestServiceProvider extends ServiceProvider
PestTestCommand::class,
PestDatasetCommand::class,
]);
if (class_exists(DuskCommand::class)) {
$this->commands([
PestDuskCommand::class,
]);
}
}
}
}

View File

@ -78,7 +78,7 @@ final class TestCall
* Runs the current test multiple times with
* each item of the given `iterable`.
*
* @param \Closure|iterable<int, mixed>|string $data
* @param \Closure|iterable<int|string, mixed>|string $data
*/
public function with($data): TestCall
{

View File

@ -6,5 +6,5 @@ namespace Pest;
function version(): string
{
return '0.3.12';
return '0.3.15';
}

View File

@ -0,0 +1,33 @@
<?php
declare(strict_types=1);
namespace Pest\Support;
use Closure;
final class Extendable
{
/**
* The extendable class.
*
* @var string
*/
private $extendableClass;
/**
* Creates a new extendable instance.
*/
public function __construct(string $extendableClass)
{
$this->extendableClass = $extendableClass;
}
/**
* Register a custom extend.
*/
public function extend(string $name, Closure $extend): void
{
$this->extendableClass::extend($name, $extend);
}
}

View File

@ -9,6 +9,7 @@ use Pest\PendingObjects\BeforeEachCall;
use Pest\PendingObjects\TestCall;
use Pest\PendingObjects\UsesCall;
use Pest\Support\Backtrace;
use Pest\Support\Extendable;
use Pest\Support\HigherOrderTapProxy;
use Pest\TestSuite;
use PHPUnit\Framework\TestCase;
@ -111,9 +112,13 @@ function afterAll(Closure $closure = null): void
*
* @param mixed $value the Value
*
* @return Expectation
* @return Expectation|Extendable
*/
function expect($value)
function expect($value = null)
{
if (func_num_args() === 0) {
return new Extendable(Expectation::class);
}
return test()->expect($value);
}

View File

@ -2,6 +2,12 @@
PASS Tests\CustomTestCase\ExecutedTest
✓ that gets executed
PASS Tests\Expect\extend
✓ it macros true is true
✓ it macros false is not true
✓ it macros true is true with argument
✓ it macros false is not true with argument
PASS Tests\Expect\not
✓ not property calls
@ -404,5 +410,5 @@
✓ depends run test only once
✓ depends works with the correct test name
Tests: 7 skipped, 238 passed
Tests: 7 skipped, 242 passed

29
tests/Expect/extend.php Normal file
View File

@ -0,0 +1,29 @@
<?php
expect()->extend('toBeAMacroExpectation', function () {
$this->toBeTrue();
return $this;
});
expect()->extend('toBeAMacroExpectationWithArguments', function (bool $value) {
$this->toBe($value);
return $this;
});
it('macros true is true', function () {
expect(true)->toBeAMacroExpectation();
});
it('macros false is not true', function () {
expect(false)->not->toBeAMacroExpectation();
});
it('macros true is true with argument', function () {
expect(true)->toBeAMacroExpectationWithArguments(true);
});
it('macros false is not true with argument', function () {
expect(false)->not->toBeAMacroExpectationWithArguments(true);
});