Compare commits

...

25 Commits

Author SHA1 Message Date
17d407a26a Updates changelog 2021-06-07 15:27:33 +01:00
cdc3bd3f45 Merge pull request #308 from titouanmathis/fix/test-key-separator
Fix/test key separator
2021-06-07 15:22:05 +01:00
95b4192c0d Fix visual success test 2021-06-07 10:40:11 +02:00
4c911cd0eb docs: update changelog 2021-06-07 08:59:27 +01:00
bb13bdaa80 docs: updates changelog 2021-06-06 01:07:27 +01:00
10e7cbe006 Merge pull request #310 from bigint/master
Update phpunit/phpunit to 9.5.5
2021-06-05 16:29:02 +01:00
0ad232e9de Update phpunit/phpunit to 9.5.5 2021-06-05 20:47:57 +05:30
574cd11a40 Add tests 2021-06-04 02:08:12 +02:00
c04d6d946d Fix a bug where plugins could not be used in a path containing an @
Fix #307
2021-06-03 14:15:20 +02:00
91eff755fd Merge pull request #306 from owenvoke/feature/lock-plugins
chore(deps): update minimum plugin versions
2021-06-02 12:43:05 +01:00
c05d287fcc chore(deps): update minimum plugin versions 2021-06-02 09:24:07 +01:00
9133b88d65 release: 1.3.0 2021-05-23 22:06:11 +01:00
93b9afbd27 docs: updates changelog 2021-05-23 22:05:46 +01:00
6c6bba2a04 tests: updates snapshots 2021-05-23 22:02:06 +01:00
dd24b7e347 Merge pull request #300 from pestphp/feat-function_exists
Wrap functions in function_exists
2021-05-23 21:47:25 +01:00
ce896b9c83 Merge pull request #302 from def-studio/show-only-name-for-named-datasets
hides dataset values if they have a name
2021-05-23 21:46:59 +01:00
a3c1a61b59 updates tests
Took 1 minute
2021-05-23 22:17:35 +02:00
98c62f4b1d show only name for named datasets
Took 4 minutes
2021-05-23 22:16:29 +02:00
dd78cc9a50 Wrap functions in function_exists 2021-05-19 09:47:29 +02:00
9027411004 feat(mock-plugin): moves mock stuff to their own plugin 2021-05-15 23:43:37 +01:00
9394aa4649 Merge pull request #289 from pestphp/feat/mock
feat: adds built-in mocking
2021-05-15 01:03:07 +01:00
88dc74bbe4 feat(mock): updates tests 2021-05-15 01:02:58 +01:00
7023cec432 feat(mock): updates tests 2021-05-15 01:01:46 +01:00
99d6fb9f5f feat(mock): updates tests 2021-05-14 23:59:50 +01:00
c9f723530d feat(mock): adds work in progress 2021-05-14 23:52:24 +01:00
14 changed files with 203 additions and 128 deletions

View File

@ -4,6 +4,24 @@ 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/).
## [v.1.3.2 (2021-06-07)](https://github.com/pestphp/pest/compare/v1.3.1...v1.3.2)
### Fixed
- Test cases with the @ symbol in the directory fail ([#308](https://github.com/pestphp/pest/pull/308))
## [v1.3.1 (2021-06-06)](https://github.com/pestphp/pest/compare/v1.3.0...v1.3.1)
### Added
- Added for PHPUnit 9.5.5 ([#310](https://github.com/pestphp/pest/pull/310))
### Changed
- Lock minimum Pest plugin versions ([#306](https://github.com/pestphp/pest/pull/306))
## [v1.3.0 (2021-05-23)](https://github.com/pestphp/pest/compare/v1.2.1...v1.3.0)
### Added
- Named datasets no longer show the arguments ([#302](https://github.com/pestphp/pest/pull/302))
### Fixed
- Wraps global functions within `function_exists` ([#300](https://github.com/pestphp/pest/pull/300))
## [v1.2.1 (2021-05-14)](https://github.com/pestphp/pest/compare/v1.2.0...v1.2.1)
### Fixed
- Laravel commands failing with new `--test-directory` option ([#297](https://github.com/pestphp/pest/pull/297))

View File

@ -21,9 +21,9 @@
"nunomaduro/collision": "^5.0",
"pestphp/pest-plugin": "^1.0",
"pestphp/pest-plugin-coverage": "^1.0",
"pestphp/pest-plugin-expectations": "^1.0",
"pestphp/pest-plugin-init": "^1.0",
"phpunit/phpunit": ">= 9.3.7 <= 9.5.4"
"pestphp/pest-plugin-expectations": "^1.3",
"pestphp/pest-plugin-init": "^1.1",
"phpunit/phpunit": ">= 9.3.7 <= 9.5.5"
},
"autoload": {
"psr-4": {
@ -46,7 +46,6 @@
"illuminate/console": "^8.32.1",
"illuminate/support": "^8.32.1",
"laravel/dusk": "^6.13.0",
"mockery/mockery": "^1.4.3",
"pestphp/pest-dev-tools": "dev-master"
},
"minimum-stability": "dev",

View File

@ -111,8 +111,10 @@ final class Datasets
{
$exporter = new Exporter();
$nameInsert = is_string($key) ? \sprintf('data set "%s" ', $key) : '';
if (is_int($key)) {
return \sprintf(' with (%s)', $exporter->shortenedRecursiveExport($data));
}
return \sprintf(' with %s(%s)', $nameInsert, $exporter->shortenedRecursiveExport($data));
return \sprintf(' with data set "%s"', $key);
}
}

View File

@ -0,0 +1,24 @@
<?php
declare(strict_types=1);
namespace Pest\Exceptions;
use InvalidArgumentException;
use NunoMaduro\Collision\Contracts\RenderlessEditor;
use NunoMaduro\Collision\Contracts\RenderlessTrace;
use Symfony\Component\Console\Exception\ExceptionInterface;
/**
* @internal
*/
final class MissingDependency extends InvalidArgumentException implements ExceptionInterface, RenderlessEditor, RenderlessTrace
{
/**
* Creates a new instance of missing dependency.
*/
public function __construct(string $feature, string $dependency)
{
parent::__construct(sprintf('The feature "%s" requires "%s".', $feature, $dependency));
}
}

View File

@ -12,95 +12,111 @@ use Pest\Support\HigherOrderTapProxy;
use Pest\TestSuite;
use PHPUnit\Framework\TestCase;
/**
* Runs the given closure before all tests in the current file.
*/
function beforeAll(Closure $closure): void
{
TestSuite::getInstance()->beforeAll->set($closure);
}
/**
* Runs the given closure before each test in the current file.
*
* @return BeforeEachCall|TestCase|mixed
*/
function beforeEach(Closure $closure = null): BeforeEachCall
{
$filename = Backtrace::file();
return new BeforeEachCall(TestSuite::getInstance(), $filename, $closure);
}
/**
* Registers the given dataset.
*
* @param Closure|iterable<int|string, mixed> $dataset
*/
function dataset(string $name, $dataset): void
{
Datasets::set($name, $dataset);
}
/**
* The uses function binds the given
* arguments to test closures.
*/
function uses(string ...$classAndTraits): UsesCall
{
$filename = Backtrace::file();
return new UsesCall($filename, $classAndTraits);
}
/**
* Adds the given closure as a test. The first argument
* is the test description; the second argument is
* a closure that contains the test expectations.
*
* @return TestCall|TestCase|mixed
*/
function test(string $description = null, Closure $closure = null)
{
if ($description === null && TestSuite::getInstance()->test !== null) {
return new HigherOrderTapProxy(TestSuite::getInstance()->test);
if (!function_exists('beforeAll')) {
/**
* Runs the given closure before all tests in the current file.
*/
function beforeAll(Closure $closure): void
{
TestSuite::getInstance()->beforeAll->set($closure);
}
$filename = Backtrace::testFile();
return new TestCall(TestSuite::getInstance(), $filename, $description, $closure);
}
/**
* Adds the given closure as a test. The first argument
* is the test description; the second argument is
* a closure that contains the test expectations.
*
* @return TestCall|TestCase|mixed
*/
function it(string $description, Closure $closure = null): TestCall
{
$description = sprintf('it %s', $description);
if (!function_exists('beforeEach')) {
/**
* Runs the given closure before each test in the current file.
*
* @return BeforeEachCall|TestCase|mixed
*/
function beforeEach(Closure $closure = null): BeforeEachCall
{
$filename = Backtrace::file();
return test($description, $closure);
return new BeforeEachCall(TestSuite::getInstance(), $filename, $closure);
}
}
/**
* Runs the given closure after each test in the current file.
*
* @return AfterEachCall|TestCase|mixed
*/
function afterEach(Closure $closure = null): AfterEachCall
{
$filename = Backtrace::file();
return new AfterEachCall(TestSuite::getInstance(), $filename, $closure);
if (!function_exists('dataset')) {
/**
* Registers the given dataset.
*
* @param Closure|iterable<int|string, mixed> $dataset
*/
function dataset(string $name, $dataset): void
{
Datasets::set($name, $dataset);
}
}
/**
* Runs the given closure after all tests in the current file.
*/
function afterAll(Closure $closure): void
{
TestSuite::getInstance()->afterAll->set($closure);
if (!function_exists('uses')) {
/**
* The uses function binds the given
* arguments to test closures.
*/
function uses(string ...$classAndTraits): UsesCall
{
$filename = Backtrace::file();
return new UsesCall($filename, $classAndTraits);
}
}
if (!function_exists('test')) {
/**
* Adds the given closure as a test. The first argument
* is the test description; the second argument is
* a closure that contains the test expectations.
*
* @return TestCall|TestCase|mixed
*/
function test(string $description = null, Closure $closure = null)
{
if ($description === null && TestSuite::getInstance()->test !== null) {
return new HigherOrderTapProxy(TestSuite::getInstance()->test);
}
$filename = Backtrace::testFile();
return new TestCall(TestSuite::getInstance(), $filename, $description, $closure);
}
}
if (!function_exists('it')) {
/**
* Adds the given closure as a test. The first argument
* is the test description; the second argument is
* a closure that contains the test expectations.
*
* @return TestCall|TestCase|mixed
*/
function it(string $description, Closure $closure = null): TestCall
{
$description = sprintf('it %s', $description);
return test($description, $closure);
}
}
if (!function_exists('afterEach')) {
/**
* Runs the given closure after each test in the current file.
*
* @return AfterEachCall|TestCase|mixed
*/
function afterEach(Closure $closure = null): AfterEachCall
{
$filename = Backtrace::file();
return new AfterEachCall(TestSuite::getInstance(), $filename, $closure);
}
}
if (!function_exists('afterAll')) {
/**
* Runs the given closure after all tests in the current file.
*/
function afterAll(Closure $closure): void
{
TestSuite::getInstance()->afterAll->set($closure);
}
}

View File

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

View File

@ -41,7 +41,6 @@ final class AfterEachRepository
return ChainableClosure::from(function (): void {
if (class_exists(Mockery::class)) {
/* @phpstan-ignore-next-line */
if ($container = Mockery::getContainer()) {
/* @phpstan-ignore-next-line */
$this->addToAssertionCount($container->mockery_getExpectationCount());

View File

@ -19,6 +19,11 @@ use PHPUnit\Framework\TestCase;
*/
final class TestRepository
{
/**
* @var string
*/
private const SEPARATOR = '>>>';
/**
* @var array<string, TestCaseFactory>
*/
@ -50,7 +55,7 @@ final class TestRepository
[$classOrTraits, $groups, $hooks] = $uses;
$setClassName = function (TestCaseFactory $testCase, string $key) use ($path, $classOrTraits, $groups, $startsWith, $hooks): void {
[$filename] = explode('@', $key);
[$filename] = explode(self::SEPARATOR, $key);
if ((!is_dir($path) && $filename === $path) || (is_dir($path) && $startsWith($filename, $path))) {
foreach ($classOrTraits as $class) { /** @var string $class */
@ -131,10 +136,10 @@ final class TestRepository
throw ShouldNotHappen::fromMessage('Trying to create a test without description.');
}
if (array_key_exists(sprintf('%s@%s', $test->filename, $test->description), $this->state)) {
if (array_key_exists(sprintf('%s%s%s', $test->filename, self::SEPARATOR, $test->description), $this->state)) {
throw new TestAlreadyExist($test->filename, $test->description);
}
$this->state[sprintf('%s@%s', $test->filename, $test->description)] = $test;
$this->state[sprintf('%s%s%s', $test->filename, self::SEPARATOR, $test->description)] = $test;
}
}

View File

@ -40,8 +40,8 @@
✓ eager wrapped registered datasets with (1)
✓ eager wrapped registered datasets with (2)
✓ eager registered wrapped datasets did the job right
✓ named datasets with data set "one" (1)
✓ named datasets with data set "two" (2)
✓ named datasets with data set "one"
✓ named datasets with data set "two"
✓ named datasets did the job right
✓ lazy named datasets with (Bar Object (...))
✓ it creates unique test case names with ('Name 1', Pest\Plugin Object (), true) #1
@ -63,6 +63,7 @@
✓ it allows to call underlying protected/private methods
✓ it throws error if method do not exist
✓ it can forward unexpected calls to any global function
✓ it can use helpers from helpers file
PASS Tests\Features\HigherOrderTests
✓ it proxies calls to object
@ -76,9 +77,6 @@
✓ it can call chained macro method
✓ it will throw exception from call if no macro exists
PASS Tests\Features\Mocks
✓ it has bar
PASS Tests\Features\PendingHigherOrderTests
✓ get 'foo' → get 'bar' → expect true → toBeTrue
✓ get 'foo' → expect true → toBeTrue
@ -124,6 +122,10 @@
PASS Tests\PHPUnit\CustomAffixes\AdditionalFileExtensionspec
✓ it runs file names like `AdditionalFileExtension.spec.php`
PASS Tests\PHPUnit\CustomAffixes\FolderWithAn\ExampleTest
✓ custom traits can be used
✓ trait applied in this file
PASS Tests\PHPUnit\CustomAffixes\ManyExtensionsclasstest
✓ it runs file names like `ManyExtensions.class.test.php`
@ -170,7 +172,8 @@
✓ it outputs the help information when --help is used
PASS Tests\Unit\Datasets
✓ it show the names of named datasets in their description
✓ it show only the names of named datasets in their description
✓ it show the actual dataset of non-named datasets in their description
PASS Tests\Unit\Plugins\Version
✓ it outputs the version when --version is used
@ -221,5 +224,5 @@
✓ it is a test
✓ it uses correct parent class
Tests: 7 skipped, 119 passed
Tests: 7 skipped, 122 passed

View File

@ -42,3 +42,5 @@ it('throws error if method do not exist', function () {
})->throws(\ReflectionException::class, 'Call to undefined method PHPUnit\Framework\TestCase::name()');
it('can forward unexpected calls to any global function')->_assertThat();
it('can use helpers from helpers file')->myAssertTrue(true);

View File

@ -1,17 +0,0 @@
<?php
use function Tests\mock;
interface Foo
{
public function bar(): int;
}
it('has bar', function () {
$mock = mock(Foo::class);
$mock->shouldReceive('bar')
->times(1)
->andReturn(2);
$mock->bar();
});

View File

@ -1,11 +1,6 @@
<?php
namespace Tests;
use Mockery;
use Mockery\MockInterface;
function mock(string $class): MockInterface
function myAssertTrue($value)
{
return Mockery::mock($class);
test()->assertTrue($value);
}

View File

@ -0,0 +1,19 @@
<?php
declare(strict_types=1);
class MyCustomClassTest extends PHPUnit\Framework\TestCase
{
public function assertTrueIsTrue()
{
$this->assertTrue(true);
}
}
uses(MyCustomClassTest::class);
test('custom traits can be used', function () {
$this->assertTrueIsTrue();
});
test('trait applied in this file')->assertTrueIsTrue();

View File

@ -2,12 +2,22 @@
use Pest\Datasets;
it('show the names of named datasets in their description', function () {
it('show only the names of named datasets in their description', function () {
$descriptions = array_keys(Datasets::resolve('test description', [
'one' => [1],
'two' => [[2]],
]));
expect($descriptions[0])->toBe('test description with data set "one" (1)');
expect($descriptions[1])->toBe('test description with data set "two" (array(2))');
expect($descriptions[0])->toBe('test description with data set "one"');
expect($descriptions[1])->toBe('test description with data set "two"');
});
it('show the actual dataset of non-named datasets in their description', function () {
$descriptions = array_keys(Datasets::resolve('test description', [
[1],
[[2]],
]));
expect($descriptions[0])->toBe('test description with (1)');
expect($descriptions[1])->toBe('test description with (array(2))');
});