This commit is contained in:
Nuno Maduro
2020-05-11 18:38:30 +02:00
commit de2929077b
112 changed files with 6211 additions and 0 deletions

View File

@ -0,0 +1,130 @@
PASS Tests\CustomTestCase\PhpunitTest
✓ that gets executed
PASS Tests\Features\AfterAll
✓ deletes file after all
PASS Tests\Features\AfterEach
✓ it does not get executed before the test
✓ it gets executed after the test
PASS Tests\Features\BeforeAll
✓ it gets executed before tests
✓ it do not get executed before each test
PASS Tests\Features\BeforeEach
✓ it gets executed before each test
✓ it gets executed before each test once again
PASS Tests\Features\Datasets
✓ it throws exception if dataset does not exist
✓ it throws exception if dataset already exist
✓ it sets closures
✓ it sets arrays
✓ it gets bound to test case object with ('a')
✓ it gets bound to test case object with ('b')
✓ it truncates the description with (' fooo fooo fooo fooo fooo fooo fooo f...oo fooo')
✓ lazy datasets with (1)
✓ lazy datasets with (2)
✓ lazy datasets did the job right
✓ eager datasets with (1)
✓ eager datasets with (2)
✓ eager datasets did the job right
✓ lazy registered datasets with (1)
✓ lazy registered datasets with (2)
✓ lazy registered datasets did the job right
✓ eager registered datasets with (1)
✓ eager registered datasets with (2)
✓ eager registered datasets did the job right
✓ eager wrapped registered datasets with (1)
✓ eager wrapped registered datasets with (2)
✓ eager registered wrapped datasets did the job right
✓ lazy named datasets with ( bar object (...))
PASS Tests\Features\Exceptions
✓ it gives access the the underlying expect exception
✓ it catch exceptions
✓ it catch exceptions and messages
PASS Tests\Features\HigherOrderMessages
✓ it proxies calls to object
PASS Tests\Features\It
✓ it is a test
✓ it is a higher order message test
PASS Tests\Features\Mocks
✓ it has bar
WARN Tests\Features\Skip
✓ it do not skips
s it skips with truthy
s it skips with truthy condition by default
s it skips with message → skipped because bar
s it skips with truthy closure condition
✓ it do not skips with falsy closure condition
s it skips with condition and messsage → skipped because foo
PASS Tests\Features\Test
✓ a test
✓ higher order message test
PASS Tests\Fixtures\DirectoryWithTests\ExampleTest
✓ it example
PASS Tests\Fixtures\ExampleTest
✓ it example
PASS Tests\PHPUnit\CustomTestCase\UsesPerDirectory
✓ closure was bound to custom test case
PASS Tests\PHPUnit\CustomTestCaseInSubFolders\SubFolder\SubFolder\UsesPerSubDirectory
✓ closure was bound to custom test case
PASS Tests\PHPUnit\CustomTestCaseInSubFolders\SubFolder2\UsesPerFile
✓ custom traits can be used
✓ trait applied in this file
PASS Tests\Playground
✓ basic
PASS Tests\Unit\Actions\AddsCoverage
✓ it adds coverage if --coverage exist
✓ it adds coverage if --min exist
PASS Tests\Unit\Actions\AddsDefaults
✓ it sets defaults
✓ it does not override options
PASS Tests\Unit\Actions\AddsTests
✓ default php unit tests
✓ it removes warnings
PASS Tests\Unit\Actions\ValidatesConfiguration
✓ it throws exception when configuration not found
✓ it throws exception when `process isolation` is true
✓ it do not throws exception when `process isolation` is false
PASS Tests\Unit\Console\Coverage
✓ it generates coverage based on file input
PASS Tests\Unit\Support\Backtrace
✓ it gets file name from called file
PASS Tests\Unit\Support\Reflection
✓ it gets file name from closure
✓ it gets property values
PASS Tests\Unit\TestSuite
✓ it does not allow to add the same test description twice
PASS Tests\Visual\SingleTestOrDirectory
✓ allows to run a single test
✓ allows to run a directory
WARN Tests\Visual\Success
s visual snapshot of test suite on success
Tests: 6 skipped, 65 passed
Time: 2.50s

5
tests/Autoload.php Normal file
View File

@ -0,0 +1,5 @@
<?php
if (class_exists(NunoMaduro\Collision\Provider::class)) {
(new NunoMaduro\Collision\Provider())->register();
}

View File

@ -0,0 +1,15 @@
<?php
dataset('numbers.closure', function () {
yield [1];
yield [2];
});
dataset('numbers.closure.wrapped', function () {
yield 1;
yield 2;
});
dataset('numbers.array', [[1], [2]]);
dataset('numbers.array.wrapped', [1, 2]);

View File

@ -0,0 +1,15 @@
<?php
$file = __DIR__ . DIRECTORY_SEPARATOR . 'after-all-test';
afterAll(function () use ($file) {
unlink($file);
});
test('deletes file after all', function () use ($file) {
file_put_contents($file, 'foo');
assertFileExists($file);
register_shutdown_function(function () use ($file) {
assertFileNotExists($file);
});
});

View File

@ -0,0 +1,20 @@
<?php
$state = new stdClass();
beforeEach(function () use ($state) {
$this->state = $state;
});
afterEach(function () use ($state) {
$this->state->bar = 2;
});
it('does not get executed before the test', function () {
assertFalse(property_exists($this->state, 'bar'));
});
it('gets executed after the test', function () {
assertTrue(property_exists($this->state, 'bar'));
assertEquals(2, $this->state->bar);
});

View File

@ -0,0 +1,18 @@
<?php
$foo = new \stdClass();
$foo->bar = 0;
beforeAll(function () use ($foo) {
$foo->bar++;
});
it('gets executed before tests', function () use ($foo) {
assertEquals($foo->bar, 1);
$foo->bar = 'changed';
});
it('do not get executed before each test', function () use ($foo) {
assertEquals($foo->bar, 'changed');
});

View File

@ -0,0 +1,15 @@
<?php
beforeEach(function () {
$this->bar = 2;
});
it('gets executed before each test', function () {
assertEquals($this->bar, 2);
$this->bar = 'changed';
});
it('gets executed before each test once again', function () {
assertEquals($this->bar, 2);
});

108
tests/Features/Datasets.php Normal file
View File

@ -0,0 +1,108 @@
<?php
use Pest\Datasets;
use Pest\Exceptions\DatasetAlreadyExist;
use Pest\Exceptions\DatasetDoesNotExist;
it('throws exception if dataset does not exist', function () {
$this->expectException(DatasetDoesNotExist::class);
$this->expectExceptionMessage("A dataset with the name `first` does not exist. You can create it using `dataset('first', ['a', 'b']);`.");
Datasets::get('first');
});
it('throws exception if dataset already exist', function () {
Datasets::set('second', [[]]);
$this->expectException(DatasetAlreadyExist::class);
$this->expectExceptionMessage('A dataset with the name `second` already exist.');
Datasets::set('second', [[]]);
});
it('sets closures', function () {
Datasets::set('foo', function () {
yield [1];
});
assertEquals([[1]], iterator_to_array(Datasets::get('foo')()));
});
it('sets arrays', function () {
Datasets::set('bar', [[2]]);
assertEquals([[2]], Datasets::get('bar'));
});
it('gets bound to test case object', function () {
$this->assertTrue(true);
})->with([['a'], ['b']]);
test('it truncates the description', function () {
assertTrue(true);
// it gets tested by the integration test
})->with([str_repeat('Fooo', 10000000)]);
$state = new stdClass();
$state->text = '';
$datasets = [[1], [2]];
test('lazy datasets', function ($text) use ($state, $datasets) {
$state->text .= $text;
assertTrue(in_array([$text], $datasets));
})->with($datasets);
test('lazy datasets did the job right', function () use ($state) {
assertEquals('12', $state->text);
});
$state->text = '';
test('eager datasets', function ($text) use ($state, $datasets) {
$state->text .= $text;
assertTrue(in_array([$text], $datasets));
})->with(function () use ($datasets) {
return $datasets;
});
test('eager datasets did the job right', function () use ($state) {
assertEquals('1212', $state->text);
});
test('lazy registered datasets', function ($text) use ($state, $datasets) {
$state->text .= $text;
assertTrue(in_array([$text], $datasets));
})->with('numbers.array');
test('lazy registered datasets did the job right', function () use ($state) {
assertEquals('121212', $state->text);
});
test('eager registered datasets', function ($text) use ($state, $datasets) {
$state->text .= $text;
assertTrue(in_array([$text], $datasets));
})->with('numbers.closure');
test('eager registered datasets did the job right', function () use ($state) {
assertEquals('12121212', $state->text);
});
test('eager wrapped registered datasets', function ($text) use ($state, $datasets) {
$state->text .= $text;
assertTrue(in_array([$text], $datasets));
})->with('numbers.closure.wrapped');
test('eager registered wrapped datasets did the job right', function () use ($state) {
assertEquals('1212121212', $state->text);
});
class Bar
{
public $name = 1;
}
$namedDatasets = [
new Bar(),
];
test('lazy named datasets', function ($text) use ($state, $datasets) {
assertTrue(true);
})->with($namedDatasets);

View File

@ -0,0 +1,15 @@
<?php
it('gives access the the underlying expectException', function () {
$this->expectException(InvalidArgumentException::class);
throw new InvalidArgumentException();
});
it('catch exceptions', function () {
throw new Exception('Something bad happened');
})->throws(Exception::class);
it('catch exceptions and messages', function () {
throw new Exception('Something bad happened');
})->throws(Exception::class, 'Something bad happened');

View File

@ -0,0 +1,7 @@
<?php
beforeEach()->assertTrue(true);
it('proxies calls to object')->assertTrue(true);
afterEach()->assertTrue(true);

7
tests/Features/It.php Normal file
View File

@ -0,0 +1,7 @@
<?php
it('is a test', function () {
assertArrayHasKey('key', ['key' => 'foo']);
});
it('is a higher order message test')->assertTrue(true);

15
tests/Features/Mocks.php Normal file
View File

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

29
tests/Features/Skip.php Normal file
View File

@ -0,0 +1,29 @@
<?php
it('do not skips')
->skip(false)
->assertTrue(true);
it('skips with truthy')
->skip(1)
->assertTrue(false);
it('skips with truthy condition by default')
->skip()
->assertTrue(false);
it('skips with message')
->skip('skipped because bar')
->assertTrue(false);
it('skips with truthy closure condition')
->skip(function () { return '1'; })
->assertTrue(false);
it('do not skips with falsy closure condition')
->skip(function () { return false; })
->assertTrue(true);
it('skips with condition and messsage')
->skip(true, 'skipped because foo')
->assertTrue(false);

7
tests/Features/Test.php Normal file
View File

@ -0,0 +1,7 @@
<?php
test('a test', function () {
assertArrayHasKey('key', ['key' => 'foo']);
});
test('higher order message test')->assertTrue(true);

View File

@ -0,0 +1,27 @@
<?php
$foo = new stdClass();
$foo->beforeAll = false;
$foo->beforeEach = false;
$foo->afterEach = false;
$foo->afterAll = false;
beforeAll(function () {
$foo->beforeAll = true;
});
beforeEach(function () {
$foo->beforeEach = true;
});
afterEach(function () {
$foo->afterEach = true;
});
afterAll(function () {
$foo->afterAll = true;
});
register_shutdown_function(function () use ($foo) {
assertFalse($foo->beforeAll);
assertFalse($foo->beforeEach);
assertFalse($foo->afterEach);
assertFalse($foo->afterAll);
});

View File

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

View File

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

View File

@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<phpunit xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="./vendor/phpunit/phpunit/phpunit.xsd"
bootstrap="vendor/autoload.php"
colors="true"
processIsolation="true"
>
</phpunit>

View File

@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<phpunit xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="./vendor/phpunit/phpunit/phpunit.xsd"
bootstrap="vendor/autoload.php"
colors="true"
processIsolation="false"
>
</phpunit>

View File

@ -0,0 +1,16 @@
<?php
declare(strict_types=1);
namespace Tests\CustomTestCase;
use function PHPUnit\Framework\assertTrue;
use PHPUnit\Framework\TestCase;
class CustomTestCase extends TestCase
{
public function assertCustomTrue()
{
assertTrue(true);
}
}

View File

@ -0,0 +1,23 @@
<?php
declare(strict_types=1);
namespace Tests\CustomTestCase;
use function PHPUnit\Framework\assertTrue;
use PHPUnit\Framework\TestCase;
class PhpunitTest extends TestCase
{
public static $executed = false;
/** @test */
public function testThatGetsExecuted(): void
{
self::$executed = true;
$this->assertTrue(true);
}
}
// register_shutdown_function(fn () => assertTrue(PhpunitTest::$executed));

View File

@ -0,0 +1,7 @@
<?php
uses(Tests\CustomTestCase\CustomTestCase::class)->in(__DIR__);
test('closure was bound to CustomTestCase', function () {
$this->assertCustomTrue();
});

View File

@ -0,0 +1,15 @@
<?php
declare(strict_types=1);
namespace Tests\SubFolder\SubFolder\SubFolder;
use PHPUnit\Framework\TestCase;
class CustomTestCaseInSubFolder extends TestCase
{
public function assertCustomInSubFolderTrue()
{
assertTrue(true);
}
}

View File

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

View File

@ -0,0 +1,25 @@
<?php
trait MyCustomTrait
{
public function assertFalseIsFalse()
{
assertFalse(false);
}
}
class MyCustomClass extends PHPUnit\Framework\TestCase
{
public function assertTrueIsTrue()
{
assertTrue(true);
}
}
uses(MyCustomClass::class, MyCustomTrait::class);
test('custom traits can be used', function () {
$this->assertTrueIsTrue();
});
test('trait applied in this file')->assertTrueIsTrue();

3
tests/PHPUnit/Pest.php Normal file
View File

@ -0,0 +1,3 @@
<?php
uses(Tests\SubFolder\SubFolder\SubFolder\CustomTestCaseInSubFolder::class)->in('CustomTestCaseInSubFolders/SubFolder');

3
tests/Pest.php Normal file
View File

@ -0,0 +1,3 @@
<?php
uses()->group('integration')->in('Visual');

5
tests/Playground.php Normal file
View File

@ -0,0 +1,5 @@
<?php
test('basic', function () {
assertTrue(true);
});

View File

@ -0,0 +1,32 @@
<?php
use Pest\Actions\AddsCoverage;
use Pest\TestSuite;
it('adds coverage if --coverage exist', function () {
$testSuite = new TestSuite(getcwd());
assertFalse($testSuite->coverage);
$arguments = AddsCoverage::from($testSuite, []);
assertEquals([], $arguments);
assertFalse($testSuite->coverage);
$arguments = AddsCoverage::from($testSuite, ['--coverage']);
assertEquals(['--coverage-php', \Pest\Console\Coverage::getPath()], $arguments);
assertTrue($testSuite->coverage);
});
it('adds coverage if --min exist', function () {
$testSuite = new TestSuite(getcwd());
assertEquals($testSuite->coverageMin, 0.0);
assertFalse($testSuite->coverage);
AddsCoverage::from($testSuite, []);
assertEquals($testSuite->coverageMin, 0.0);
AddsCoverage::from($testSuite, ['--min=2']);
assertEquals($testSuite->coverageMin, 2.0);
AddsCoverage::from($testSuite, ['--min=2.4']);
assertEquals($testSuite->coverageMin, 2.4);
});

View File

@ -0,0 +1,20 @@
<?php
use NunoMaduro\Collision\Adapters\Phpunit\Printer;
use Pest\Actions\AddsDefaults;
use PHPUnit\TextUI\DefaultResultPrinter;
it('sets defaults', function () {
$arguments = AddsDefaults::to(['bar' => 'foo']);
assertInstanceOf(Printer::class, $arguments['printer']);
assertEquals($arguments['bar'], 'foo');
});
it('does not override options', function () {
$defaultResultPrinter = new DefaultResultPrinter();
assertEquals(AddsDefaults::to(['printer' => $defaultResultPrinter]), [
'printer' => $defaultResultPrinter,
]);
});

View File

@ -0,0 +1,32 @@
<?php
use Pest\Actions\AddsTests;
use PHPUnit\Framework\TestCase as PhpUnitTestCase;
use PHPUnit\Framework\TestSuite;
use PHPUnit\Framework\WarningTestCase;
$closure = function () {
};
$pestTestCase = new class() extends \PHPUnit\Framework\TestCase {
};
test('default php unit tests', function () {
$testSuite = new TestSuite();
$phpUnitTestCase = new class() extends PhpUnitTestCase {
};
$testSuite->addTest($phpUnitTestCase);
assertCount(1, $testSuite->tests());
AddsTests::to($testSuite, new \Pest\TestSuite(getcwd()));
assertCount(1, $testSuite->tests());
});
it('removes warnings', function () use ($pestTestCase) {
$testSuite = new TestSuite();
$warningTestCase = new WarningTestCase('No tests found in class "Pest\TestCase".');
$testSuite->addTest($warningTestCase);
AddsTests::to($testSuite, new \Pest\TestSuite(getcwd()));
assertCount(0, $testSuite->tests());
});

View File

@ -0,0 +1,42 @@
<?php
use Pest\Actions\ValidatesConfiguration;
use Pest\Exceptions\AttributeNotSupportedYet;
use Pest\Exceptions\FileOrFolderNotFound;
it('throws exception when configuration not found', function () {
$this->expectException(FileOrFolderNotFound::class);
ValidatesConfiguration::in([
'configuration' => 'foo',
]);
});
it('throws exception when `process isolation` is true', function () {
$this->expectException(AttributeNotSupportedYet::class);
$this->expectExceptionMessage('The PHPUnit attribute `processIsolation` with value `true` is not supported yet.');
$filename = implode(DIRECTORY_SEPARATOR, [
dirname(__DIR__, 2),
'Fixtures',
'phpunit-in-isolation.xml',
]);
ValidatesConfiguration::in([
'configuration' => $filename,
]);
});
it('do not throws exception when `process isolation` is false', function () {
$filename = implode(DIRECTORY_SEPARATOR, [
dirname(__DIR__, 2),
'Fixtures',
'phpunit-not-in-isolation.xml',
]);
ValidatesConfiguration::in([
'configuration' => $filename,
]);
assertTrue(true);
});

View File

@ -0,0 +1,24 @@
<?php
use Pest\Console\Coverage;
it('generates coverage based on file input', function () {
assertEquals([
'4..6', '102',
], Coverage::getMissingCoverage(new class() {
public function getCoverageData(): array
{
return [
1 => ['foo'],
2 => ['bar'],
4 => [],
5 => [],
6 => [],
7 => null,
100 => null,
101 => ['foo'],
102 => [],
];
}
}));
});

View File

@ -0,0 +1,11 @@
<?php
use Pest\Support\Backtrace;
it('gets file name from called file', function () {
$a = function () {
return Backtrace::file();
};
assertEquals(__FILE__, $a());
});

View File

@ -0,0 +1,19 @@
<?php
use Pest\Support\Reflection;
it('gets file name from closure', function () {
$fileName = Reflection::getFileNameFromClosure(function () {});
assertEquals(__FILE__, $fileName);
});
it('gets property values', function () {
$class = new class() {
private $foo = 'bar';
};
$value = Reflection::getPropertyValue($class, 'foo');
assertEquals('bar', $value);
});

13
tests/Unit/TestSuite.php Normal file
View File

@ -0,0 +1,13 @@
<?php
use Pest\Exceptions\TestAlreadyExist;
use Pest\TestSuite;
it('does not allow to add the same test description twice', function () {
$testSuite = new TestSuite(getcwd());
$test = function () {};
$testSuite->tests->set(new \Pest\Factories\TestCaseFactory(__FILE__, 'foo', $test));
$this->expectException(TestAlreadyExist::class);
$this->expectExceptionMessage(sprintf('A test with the description `%s` already exist in the filename `%s`.', 'foo', __FILE__));
$testSuite->tests->set(new \Pest\Factories\TestCaseFactory(__FILE__, 'foo', $test));
});

View File

@ -0,0 +1,32 @@
<?php
use Symfony\Component\Process\Process;
$run = function (string $target) {
$process = new Process(['./bin/pest', $target], dirname(__DIR__, 2));
$process->run();
return preg_replace('#\\x1b[[][^A-Za-z]*[A-Za-z]#', '', $process->getOutput());
};
test('allows to run a single test', function () use ($run) {
assertStringContainsString(<<<EOF
PASS Tests\Fixtures\DirectoryWithTests\ExampleTest
it example
Tests: 1 passed
EOF, $run('tests/Fixtures/DirectoryWithTests/ExampleTest.php'));
});
test('allows to run a directory', function () use ($run) {
assertStringContainsString(<<<EOF
PASS Tests\Fixtures\DirectoryWithTests\ExampleTest
it example
PASS Tests\Fixtures\ExampleTest
it example
Tests: 2 passed
EOF, $run('tests/Fixtures'));
});

27
tests/Visual/Success.php Normal file
View File

@ -0,0 +1,27 @@
<?php
test('visual snapshot of test suite on success', function () {
$testsPath = dirname(__DIR__);
$snapshot = implode(DIRECTORY_SEPARATOR, [
$testsPath,
'.snapshots',
'success.txt',
]);
$output = function () use ($testsPath) {
$process = (new Symfony\Component\Process\Process(['./bin/pest'], dirname($testsPath), ['EXCLUDE' => 'integration', 'REBUILD_SNAPSHOTS' => false]));
$process->run();
return preg_replace('#\\x1b[[][^A-Za-z]*[A-Za-z]#', '', $process->getOutput());
};
if (getenv('REBUILD_SNAPSHOTS')) {
file_put_contents($snapshot, $output());
} elseif (!getenv('EXCLUDE')) {
$output = explode("\n", $output());
array_pop($output);
array_pop($output);
assertStringContainsString(implode("\n", $output), file_get_contents($snapshot));
}
})->skip(!getenv('REBUILD_SNAPSHOTS') && getenv('EXCLUDE'));