mirror of
https://github.com/pestphp/pest.git
synced 2026-03-06 15:57:21 +01:00
Compare commits
37 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 809fb855de | |||
| aa14f2e200 | |||
| e319bdb6d3 | |||
| fb7340b556 | |||
| 0528fec083 | |||
| 1cbaaf6e12 | |||
| dc862f60b2 | |||
| ff04d54247 | |||
| 330cf05177 | |||
| 42b5fa914c | |||
| 3b1026b7d7 | |||
| b6151e0d01 | |||
| d6db2c13c1 | |||
| 07b6ff6c04 | |||
| ac5da9e3f7 | |||
| 90fb8c602c | |||
| 3974a65a18 | |||
| 2a54b5819d | |||
| 7177791f1e | |||
| c743b10a87 | |||
| 83f8de17c8 | |||
| da20a62e49 | |||
| c8d3e1a9fa | |||
| f7705fe1c1 | |||
| cf23dfa477 | |||
| ab4787c667 | |||
| bd6b166a62 | |||
| 17340947b3 | |||
| f235d84d95 | |||
| 3c0d780696 | |||
| 16768fca9f | |||
| 95ec0a82b2 | |||
| 0a680dd06e | |||
| 152892cc38 | |||
| 9aad417fb2 | |||
| b58e0cba66 | |||
| 74864c60e1 |
42
.github/workflows/integration-tests.yml
vendored
42
.github/workflows/integration-tests.yml
vendored
@ -1,42 +0,0 @@
|
||||
name: Integration Tests
|
||||
|
||||
on:
|
||||
push:
|
||||
schedule:
|
||||
- cron: '0 0 * * *'
|
||||
|
||||
|
||||
jobs:
|
||||
ci:
|
||||
if: github.event_name != 'schedule' || github.repository == 'pestphp/pest'
|
||||
runs-on: ${{ matrix.os }}
|
||||
strategy:
|
||||
matrix:
|
||||
os: [ubuntu-latest, macos-latest, windows-latest]
|
||||
php: ['8.1', '8.2']
|
||||
dependency-version: [prefer-lowest, prefer-stable]
|
||||
|
||||
name: PHP ${{ matrix.php }} - ${{ matrix.os }} - ${{ matrix.dependency-version }}
|
||||
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Setup PHP
|
||||
uses: shivammathur/setup-php@v2
|
||||
with:
|
||||
php-version: ${{ matrix.php }}
|
||||
tools: composer:v2
|
||||
coverage: none
|
||||
|
||||
- name: Setup Problem Matches
|
||||
run: |
|
||||
echo "::add-matcher::${{ runner.tool_cache }}/php.json"
|
||||
echo "::add-matcher::${{ runner.tool_cache }}/phpunit.json"
|
||||
|
||||
- name: Install PHP dependencies
|
||||
run: composer update --${{ matrix.dependency-version }} --no-interaction --no-progress --ansi
|
||||
|
||||
- name: Integration Tests
|
||||
run: composer test:integration
|
||||
|
||||
1
.github/workflows/static.yml
vendored
1
.github/workflows/static.yml
vendored
@ -13,6 +13,7 @@ jobs:
|
||||
|
||||
runs-on: ubuntu-latest
|
||||
strategy:
|
||||
fail-fast: true
|
||||
matrix:
|
||||
dependency-version: [prefer-lowest, prefer-stable]
|
||||
|
||||
|
||||
19
.github/workflows/tests.yml
vendored
19
.github/workflows/tests.yml
vendored
@ -6,18 +6,23 @@ on:
|
||||
schedule:
|
||||
- cron: '0 0 * * *'
|
||||
|
||||
|
||||
jobs:
|
||||
ci:
|
||||
tests:
|
||||
if: github.event_name != 'schedule' || github.repository == 'pestphp/pest'
|
||||
|
||||
runs-on: ${{ matrix.os }}
|
||||
strategy:
|
||||
fail-fast: true
|
||||
matrix:
|
||||
os: [ubuntu-latest, macos-latest, windows-latest]
|
||||
symfony: ['6.4.0', '7.0.1']
|
||||
php: ['8.1', '8.2', '8.3']
|
||||
dependency-version: [prefer-lowest, prefer-stable]
|
||||
dependency_version: [prefer-lowest, prefer-stable]
|
||||
exclude:
|
||||
- php: '8.1'
|
||||
symfony: '7.0.1'
|
||||
|
||||
name: PHP ${{ matrix.php }} - ${{ matrix.os }} - ${{ matrix.dependency-version }}
|
||||
name: PHP ${{ matrix.php }} - Symfony ^${{ matrix.symfony }} - ${{ matrix.os }} - ${{ matrix.dependency_version }}
|
||||
|
||||
steps:
|
||||
- name: Checkout
|
||||
@ -36,11 +41,13 @@ jobs:
|
||||
echo "::add-matcher::${{ runner.tool_cache }}/phpunit.json"
|
||||
|
||||
- name: Install PHP dependencies
|
||||
run: composer update --${{ matrix.dependency-version }} --no-interaction --no-progress --ansi
|
||||
run: composer update --${{ matrix.dependency_version }} --no-interaction --no-progress --ansi --with="symfony/console:^${{ matrix.symfony }}"
|
||||
|
||||
- name: Unit Tests
|
||||
run: composer test:unit
|
||||
|
||||
- name: Unit Tests in Parallel
|
||||
- name: Parallel Tests
|
||||
run: composer test:parallel
|
||||
|
||||
- name: Integration Tests
|
||||
run: composer test:integration
|
||||
|
||||
2
bin/pest
2
bin/pest
@ -38,7 +38,7 @@ use Symfony\Component\Console\Output\ConsoleOutput;
|
||||
unset($args[$key]);
|
||||
}
|
||||
|
||||
if ($value === '--todos') {
|
||||
if (in_array($value, ['--todo', '--todos'], true)) {
|
||||
$todo = true;
|
||||
unset($args[$key]);
|
||||
}
|
||||
|
||||
@ -18,15 +18,15 @@
|
||||
],
|
||||
"require": {
|
||||
"php": "^8.1.0",
|
||||
"brianium/paratest": "^7.3.0",
|
||||
"brianium/paratest": "^7.3.1",
|
||||
"nunomaduro/collision": "^7.10.0|^8.0.0",
|
||||
"nunomaduro/termwind": "^1.15.1|^2.0.0",
|
||||
"pestphp/pest-plugin": "^2.1.1",
|
||||
"pestphp/pest-plugin-arch": "^2.4.1",
|
||||
"phpunit/phpunit": "^10.4.2"
|
||||
"phpunit/phpunit": "^10.5.1"
|
||||
},
|
||||
"conflict": {
|
||||
"phpunit/phpunit": ">10.4.2",
|
||||
"phpunit/phpunit": ">10.5.1",
|
||||
"sebastian/exporter": "<5.1.0",
|
||||
"webmozart/assert": "<1.11.0"
|
||||
},
|
||||
@ -52,8 +52,8 @@
|
||||
},
|
||||
"require-dev": {
|
||||
"pestphp/pest-dev-tools": "^2.16.0",
|
||||
"pestphp/pest-plugin-type-coverage": "^2.4.0",
|
||||
"symfony/process": "^6.3.4"
|
||||
"pestphp/pest-plugin-type-coverage": "^2.5.0",
|
||||
"symfony/process": "^6.4.0|^7.0.1"
|
||||
},
|
||||
"minimum-stability": "dev",
|
||||
"prefer-stable": true,
|
||||
@ -109,6 +109,11 @@
|
||||
"Pest\\Plugins\\Version",
|
||||
"Pest\\Plugins\\Parallel"
|
||||
]
|
||||
},
|
||||
"phpstan": {
|
||||
"includes": [
|
||||
"extension.neon"
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
4
extension.neon
Normal file
4
extension.neon
Normal file
@ -0,0 +1,4 @@
|
||||
parameters:
|
||||
universalObjectCratesClasses:
|
||||
- Pest\Support\HigherOrderTapProxy
|
||||
- Pest\Expectation
|
||||
@ -193,6 +193,7 @@ trait Testable
|
||||
$method = TestSuite::getInstance()->tests->get(self::$__filename)->getMethod($this->name());
|
||||
|
||||
$description = $this->dataName() ? $method->description.' with '.$this->dataName() : $method->description;
|
||||
$description = htmlspecialchars(html_entity_decode($description), ENT_NOQUOTES);
|
||||
|
||||
if ($method->repetitions > 1) {
|
||||
$matches = [];
|
||||
|
||||
@ -34,8 +34,6 @@ use PHPUnit\Architecture\Elements\ObjectDescription;
|
||||
use PHPUnit\Framework\ExpectationFailedException;
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*
|
||||
* @template TValue
|
||||
*
|
||||
* @property OppositeExpectation $not Creates the opposite expectation.
|
||||
|
||||
@ -844,6 +844,7 @@ final class Expectation
|
||||
|
||||
$string = match (true) {
|
||||
is_string($this->value) => $this->value,
|
||||
is_object($this->value) && method_exists($this->value, 'toSnapshot') => $this->value->toSnapshot(),
|
||||
is_object($this->value) && method_exists($this->value, '__toString') => $this->value->__toString(),
|
||||
is_object($this->value) && method_exists($this->value, 'toString') => $this->value->toString(),
|
||||
$this->value instanceof \Illuminate\Testing\TestResponse => $this->value->getContent(), // @phpstan-ignore-line
|
||||
|
||||
@ -233,6 +233,30 @@ final class TestCall
|
||||
: $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Skips the current test unless the given test is running on Windows.
|
||||
*/
|
||||
public function onlyOnWindows(): self
|
||||
{
|
||||
return $this->skipOnMac()->skipOnLinux();
|
||||
}
|
||||
|
||||
/**
|
||||
* Skips the current test unless the given test is running on Mac.
|
||||
*/
|
||||
public function onlyOnMac(): self
|
||||
{
|
||||
return $this->skipOnWindows()->skipOnLinux();
|
||||
}
|
||||
|
||||
/**
|
||||
* Skips the current test unless the given test is running on Linux.
|
||||
*/
|
||||
public function onlyOnLinux(): self
|
||||
{
|
||||
return $this->skipOnWindows()->skipOnMac();
|
||||
}
|
||||
|
||||
/**
|
||||
* Repeats the current test the given number of times.
|
||||
*/
|
||||
|
||||
@ -6,7 +6,7 @@ namespace Pest;
|
||||
|
||||
function version(): string
|
||||
{
|
||||
return '2.24.1';
|
||||
return '2.27.0';
|
||||
}
|
||||
|
||||
function testDirectory(string $file = ''): string
|
||||
|
||||
@ -34,7 +34,7 @@ final class Parallel implements HandlesArguments
|
||||
/**
|
||||
* @var string[]
|
||||
*/
|
||||
private const UNSUPPORTED_ARGUMENTS = ['--todos', '--retry'];
|
||||
private const UNSUPPORTED_ARGUMENTS = ['--todo', '--todos', '--retry'];
|
||||
|
||||
/**
|
||||
* Whether the given command line arguments indicate that the test suite should be run in parallel.
|
||||
|
||||
@ -54,8 +54,8 @@ final class Result
|
||||
$returnCode = self::FAILURE_EXIT;
|
||||
}
|
||||
|
||||
$warnings = $result->numberOfTestsWithTestTriggeredPhpunitWarningEvents() +
|
||||
+count($result->warnings())
|
||||
$warnings = $result->numberOfTestsWithTestTriggeredPhpunitWarningEvents()
|
||||
+ count($result->warnings())
|
||||
+ count($result->phpWarnings());
|
||||
|
||||
if ($configuration->failOnWarning() && $warnings > 0) {
|
||||
|
||||
@ -190,7 +190,7 @@ final class Reflection
|
||||
}
|
||||
|
||||
$arguments[$parameter->getName()] = implode('|', array_map(
|
||||
static fn (ReflectionNamedType $type): string => $type->getName(),
|
||||
static fn (ReflectionNamedType $type): string => $type->getName(), // @phpstan-ignore-line
|
||||
($types instanceof ReflectionNamedType)
|
||||
? [$types] // NOTE: normalize as list of to handle unions
|
||||
: $types->getTypes(),
|
||||
|
||||
@ -0,0 +1,3 @@
|
||||
{
|
||||
"key": " <div class=\"container\">\n <div class=\"row\">\n <div class=\"col-md-12\">\n <h1>Snapshot<\/h1>\n <\/div>\n <\/div>\n <\/div>"
|
||||
}
|
||||
@ -1,5 +1,5 @@
|
||||
|
||||
Pest Testing Framework 2.24.1.
|
||||
Pest Testing Framework 2.27.0.
|
||||
|
||||
USAGE: pest <file> [options]
|
||||
|
||||
|
||||
@ -1,3 +1,3 @@
|
||||
|
||||
Pest Testing Framework 2.24.1.
|
||||
Pest Testing Framework 2.27.0.
|
||||
|
||||
|
||||
@ -836,6 +836,7 @@
|
||||
✓ within describe → pass with dataset with ('my-datas-set-value')
|
||||
✓ pass with toArray
|
||||
✓ pass with array
|
||||
✓ pass with toSnapshot
|
||||
✓ failures
|
||||
✓ failures with custom message
|
||||
✓ not failures
|
||||
@ -1194,6 +1195,7 @@
|
||||
✓ it show the correct description for mixed named and not-named datasets
|
||||
✓ it shows the correct description for long texts with newlines
|
||||
✓ it shows the correct description for arrays with many elements
|
||||
✓ it shows the correct description of datasets with html
|
||||
|
||||
PASS Tests\Unit\Expectations\OppositeExpectation
|
||||
✓ it throw expectation failed exception with string argument
|
||||
@ -1346,10 +1348,12 @@
|
||||
- visual snapshot of team city with ('SuccessOnly.php')
|
||||
|
||||
PASS Tests\Visual\Todo
|
||||
✓ todos
|
||||
✓ todos in parallel
|
||||
✓ todo
|
||||
✓ todo in parallel
|
||||
|
||||
WARN Tests\Visual\Version
|
||||
- visual snapshot of help command output
|
||||
|
||||
Tests: 2 deprecated, 4 warnings, 5 incomplete, 2 notices, 13 todos, 19 skipped, 962 passed (2280 assertions)
|
||||
Tests: 2 deprecated, 4 warnings, 5 incomplete, 2 notices, 13 todos, 19 skipped, 966 passed (2286 assertions)
|
||||
31
tests/.snapshots/todos.txt
Normal file
31
tests/.snapshots/todos.txt
Normal file
@ -0,0 +1,31 @@
|
||||
TODO Tests\Features\BeforeEachProxiesToTestCallWithTodo - 4 todos
|
||||
↓ is marked as todo 1
|
||||
↓ is marked as todo 2
|
||||
↓ is marked as todo 3
|
||||
↓ shouldBeMarkedAsTodo
|
||||
|
||||
TODO Tests\Features\DatasetsTests - 1 todo
|
||||
↓ forbids to define tests in Datasets dirs and Datasets.php files
|
||||
|
||||
TODO Tests\Features\Describe - 5 todos
|
||||
↓ todo
|
||||
↓ todo on hook → should not fail
|
||||
↓ todo on hook → should run
|
||||
↓ todo on describe → should not fail
|
||||
↓ todo on describe → should run
|
||||
|
||||
TODO Tests\Features\Todo - 3 todos
|
||||
↓ something todo later
|
||||
↓ something todo later chained
|
||||
↓ something todo later chained and with function body
|
||||
|
||||
PASS Tests\CustomTestCase\ChildTest
|
||||
✓ override method
|
||||
|
||||
PASS Tests\CustomTestCase\ExecutedTest
|
||||
✓ that gets executed
|
||||
|
||||
PASS Tests\CustomTestCase\ParentTest
|
||||
✓ override method
|
||||
|
||||
Tests: 13 todos, 3 passed (3 assertions)
|
||||
@ -103,6 +103,26 @@ test('pass with array', function () {
|
||||
])->toMatchSnapshot();
|
||||
});
|
||||
|
||||
test('pass with `toSnapshot`', function () {
|
||||
TestSuite::getInstance()->snapshots->save(json_encode(['key' => $this->snapshotable], JSON_PRETTY_PRINT));
|
||||
|
||||
$object = new class($this->snapshotable)
|
||||
{
|
||||
public function __construct(protected string $snapshotable)
|
||||
{
|
||||
}
|
||||
|
||||
public function toSnapshot()
|
||||
{
|
||||
return json_encode([
|
||||
'key' => $this->snapshotable,
|
||||
], JSON_PRETTY_PRINT);
|
||||
}
|
||||
};
|
||||
|
||||
expect($object)->toMatchSnapshot();
|
||||
});
|
||||
|
||||
test('failures', function () {
|
||||
TestSuite::getInstance()->snapshots->save($this->snapshotable);
|
||||
|
||||
|
||||
@ -99,3 +99,13 @@ it('shows the correct description for arrays with many elements', function () {
|
||||
|
||||
expect($descriptions[0])->toBe('([1, 2, 3, …])');
|
||||
});
|
||||
|
||||
it('shows the correct description of datasets with html', function () {
|
||||
$descriptions = array_keys(DatasetsRepository::resolve([
|
||||
[
|
||||
'<div class="flex items-center"></div>',
|
||||
],
|
||||
], __FILE__));
|
||||
|
||||
expect($descriptions[0])->toBe('(\'<div class="flex items-center"></div>\')');
|
||||
});
|
||||
|
||||
@ -20,7 +20,7 @@ $names = [
|
||||
'卜竹弓一十山' => '__pest_evaluable_卜竹弓一十山',
|
||||
'アゴデヸ' => '__pest_evaluable_アゴデヸ',
|
||||
'!p8VrB' => '__pest_evaluable__p8VrB',
|
||||
'&xe6VeKWF#n4' => '__pest_evaluable__xe6VeKWF_n4',
|
||||
'&xe6VeKWF#n4' => '__pest_evaluable__amp_xe6VeKWF_n4',
|
||||
'%%HurHUnw7zM!' => '__pest_evaluable___HurHUnw7zM_',
|
||||
'rundeliekend' => '__pest_evaluable_rundeliekend',
|
||||
'g%%c!Jt9$fy#Kf' => '__pest_evaluable_g__c_Jt9_fy_Kf',
|
||||
@ -33,7 +33,7 @@ $names = [
|
||||
'Каролин' => '__pest_evaluable_Каролин',
|
||||
'অ্যান্টার্কটিকা' => '__pest_evaluable_অ্যান্টার্কটিকা',
|
||||
'Frýdek-Místek"' => '__pest_evaluable_Frýdek_Místek_',
|
||||
'Allingåbro&' => '__pest_evaluable_Allingåbro_',
|
||||
'Allingåbro&' => '__pest_evaluable_Allingåbro_amp_',
|
||||
'Κεντροαφρικανική Δημοκρατία' => '__pest_evaluable_Κεντροαφρικανική_Δημοκρατία',
|
||||
'آذربایجان غربی' => '__pest_evaluable_آذربایجان_غربی',
|
||||
'זימבבואה' => '__pest_evaluable_זימבבואה',
|
||||
|
||||
@ -16,7 +16,7 @@ $run = function () {
|
||||
|
||||
test('parallel', function () use ($run) {
|
||||
expect($run('--exclude-group=integration'))
|
||||
->toContain('Tests: 1 deprecated, 4 warnings, 5 incomplete, 2 notices, 13 todos, 15 skipped, 951 passed (2265 assertions)')
|
||||
->toContain('Tests: 1 deprecated, 4 warnings, 5 incomplete, 2 notices, 13 todos, 15 skipped, 953 passed (2267 assertions)')
|
||||
->toContain('Parallel: 3 processes');
|
||||
})->skipOnWindows();
|
||||
|
||||
|
||||
@ -26,10 +26,18 @@ $snapshot = function ($name) {
|
||||
]));
|
||||
};
|
||||
|
||||
test('todos', function () use ($run, $snapshot) {
|
||||
expect($run('--todos', false))->toContain($snapshot('todos'));
|
||||
})->skipOnWindows();
|
||||
|
||||
test('todos in parallel', function () use ($run, $snapshot) {
|
||||
expect($run('--todos', true))->toContain($snapshot('todos'));
|
||||
})->skipOnWindows();
|
||||
|
||||
test('todo', function () use ($run, $snapshot) {
|
||||
expect($run('--todos', false))->toContain($snapshot('todo'));
|
||||
expect($run('--todo', false))->toContain($snapshot('todo'));
|
||||
})->skipOnWindows();
|
||||
|
||||
test('todo in parallel', function () use ($run, $snapshot) {
|
||||
expect($run('--todos', true))->toContain($snapshot('todo'));
|
||||
expect($run('--todo', true))->toContain($snapshot('todo'));
|
||||
})->skipOnWindows();
|
||||
|
||||
Reference in New Issue
Block a user