Compare commits

...

51 Commits

Author SHA1 Message Date
cef5c36885 release: v2.23.1 2023-10-10 15:57:14 +01:00
a343ba4a29 chore: adds PHPUnit 10.4.1 support 2023-10-10 15:57:07 +01:00
21b30b22a7 release: v2.23.0 2023-10-10 15:41:56 +01:00
449c4b6c5e chore: adds collision v8 support 2023-10-10 15:37:25 +01:00
6513ad6ced release: v2.22.1 2023-10-10 14:59:16 +01:00
12421c846e chore: adds termwind v2 support 2023-10-10 14:55:43 +01:00
a312cecede release: v2.22.0 2023-10-10 08:45:41 +01:00
4be97ed314 Merge pull request #977 from JonPurvis/to-be-url-expectation
[2.x] Adds `toBeUrl()` Expectation
2023-10-09 20:06:52 +01:00
5101b9dce3 add to be url expectation 2023-10-09 20:02:11 +01:00
2ffafd445d release: v2.21.0 2023-10-06 13:33:39 +01:00
6068ef6150 feat: adds support for PHPUnit 10.4 2023-10-06 13:33:31 +01:00
8c0b933fcd chore: bumps dependencies 2023-10-05 18:32:07 +01:00
991e02649a chore: bumps paratest 2023-10-05 09:42:56 +01:00
a8b785f69e release: v2.20.0 2023-09-29 19:05:52 +01:00
56610d886d Merge pull request #968 from JonPurvis/add-to-be-between-expectation
[2.x] Add `toBeBetween` expectation
2023-09-29 19:01:05 +01:00
be0d9e964b add toBeBetween() expectation 2023-09-22 01:55:06 +01:00
6bc9da3fe1 chore: bumps collision 2023-09-19 11:48:16 +01:00
6f54462070 fix: sync wrapper runner with paratest 2023-09-19 11:27:09 +01:00
876629b744 release: v2.19.1 2023-09-19 11:01:29 +01:00
5e74e5a19d release: v2.19.0 2023-09-19 10:48:34 +01:00
0d114e21fd chore: updates snapshots 2023-09-19 10:48:23 +01:00
95b65fe72b Merge pull request #962 from JonPurvis/construct-destruct-expectations
add toHaveConstructor() and toHaveDestructor() expectations
2023-09-18 11:37:46 +01:00
bc08f2cb55 fix style issues 2023-09-18 01:13:51 +01:00
6c73a3d90b initial commit 2023-09-18 01:00:50 +01:00
c08f33638a chore: updates release 2023-09-13 23:16:44 +01:00
6c93390c9c chore: removes changelog.md 2023-09-13 23:15:56 +01:00
b53e396aac release: v2.18.2 2023-09-13 23:14:31 +01:00
8b327aa8b4 chore: adds phpunit 10.3.4 support 2023-09-13 23:14:22 +01:00
d0c6f9bc60 Merge pull request #957 from adevade/patch-1
Switch mixed indentation to spaces only in Laravel stub for `phpunit.xml.stub`
2023-09-12 16:15:39 +01:00
b5e066939b Whoops 2023-09-12 09:04:30 +02:00
7892237408 Update Laravel phpunit.xml.stub indentation 2023-09-12 09:03:41 +02:00
74df53c72b release: v2.18.1 2023-09-11 11:38:47 +01:00
ee26457705 Merge pull request #956 from Itemshopp/phpunit-xml-stub-update
[2.x] Update phpunit.xml stub file
2023-09-11 11:32:34 +01:00
MHO
09e6a0944a Removed self closing coverage tag from phpunit xml stub files 2023-09-11 11:03:25 +02:00
MHO
bdee46043a Reformatted php unit xml tag attributes in both init stubs files 2023-09-10 13:37:26 +02:00
MHO
3e25168777 Corrected incorrect indentation in laravel phpunit xml slug 2023-09-10 13:00:55 +02:00
MHO
21b8507252 Updated Laravel init phpunit.xml stub file 2023-09-08 16:40:25 +02:00
MHO
d8e283777e Updated phpunit.xml stub file 2023-09-08 15:39:44 +02:00
2b0aa4b9c9 release: v2.18.0 2023-09-07 19:00:46 +01:00
040eb8142d chore: phpunit 10.3.3 support 2023-09-07 19:00:26 +01:00
d1aeabc9da chore: style changes 2023-09-06 12:19:27 +01:00
e4ec2b3efa chore: updates snapshots 2023-09-06 11:58:48 +01:00
dedcc6b887 Merge pull request #950 from hungthai1401/wrong_comment
[2.x] Correct some  comment messages in `OppositeExpectation`
2023-09-06 11:55:17 +01:00
2b0ed2bc45 Merge pull request #948 from hungthai1401/to_be_uuid
[2.x] Add `toBeUuid` expectation
2023-09-06 11:54:05 +01:00
9c859ae7c4 Merge branch '2.x' into to_be_uuid 2023-09-06 11:53:58 +01:00
ae0a230046 chore: improves readability 2023-09-06 11:48:53 +01:00
644fade478 Merge pull request #949 from pestphp/fix-depends-with-describe
[2.x] Fix the Usage of `depends` With `describe`
2023-09-06 11:47:34 +01:00
c9e919dd40 fix: correct comment message in OppositeExpectation 2023-09-06 08:34:48 +07:00
42323e27b1 fix: correct method name 2023-09-06 08:21:42 +07:00
3927177b23 finishing the code 2023-09-05 20:36:18 -03:00
038fd80428 feat: toBeUUID expectation 2023-09-05 08:25:02 +07:00
33 changed files with 375 additions and 319 deletions

View File

@ -1,274 +0,0 @@
# Release Notes for 2.x
## Unreleased
## [v2.17.0 (2023-09-04)](https://github.com/pestphp/pest/compare/v2.16.1...v2.17.0)
### Added
- `toHaveMethod` expectation ([#947](https://github.com/pestphp/pest/pull/947))
- `toHaveAttribute` expectation ([#934](https://github.com/pestphp/pest/pull/934))
## [v2.16.1 (2023-08-29)](https://github.com/pestphp/pest/compare/v2.16.0...v2.16.1)
> New changelog format starting this release.
### Added
* `toHaveSameSize` expectation by @hungthai1401 in https://github.com/pestphp/pest/pull/924, https://github.com/pestphp/pest/pull/930
### Fixed
* Inconsistent type have count exception by @hungthai1401 in https://github.com/pestphp/pest/pull/923
* Datasets defined in `Pest.php`
## [v2.16.0 (2023-08-21)](https://github.com/pestphp/pest/compare/v2.15.0...v2.16.0)
### Added
- `toBeDigits` ([#911](https://github.com/pestphp/pest/pull/911))
- `toBeCamelCase`, `toBeKebabCase`, `toBeSnakeCase`, `toBeStudlyCase`, `toHaveSnakeCaseKeys`, `toHaveKebabCaseKeys`, `toHaveCamelCaseKeys`, `toHaveStudlyCaseKeys`` ([#921](https://github.com/pestphp/pest/pull/921))
- native functions support on `arch` expectations, e.g: `expect('sleep')->toBeUsed();` ([#4](https://github.com/pestphp/pest-plugin-arch/pull/4))
### Changed
- `phpunit.xml` stub ([#915](https://github.com/pestphp/pest/pull/915))
### Fixed
- Nested sequences ([#895](https://github.com/pestphp/pest/pull/895))
## [v2.15.0 (2023-08-17)](https://github.com/pestphp/pest/compare/v2.14.1...v2.15.0)
### Added
- PHP 8.3 support ([0b261ef](https://github.com/pestphp/pest/commit/0b261ef97b7ceed20cbeeb2b0b41e08e0a8fcaa1))
## [v2.14.1 (2023-08-16)](https://github.com/pestphp/pest/compare/v2.14.0...v2.14.1)
### Changed
- Bumps PHPUnit to `^10.3.2` ([e012517](https://github.com/pestphp/pest/commit/e012517b1643002b36a68096f4a5e26682b1e175))
## [v2.14.0 (2023-08-14)](https://github.com/pestphp/pest/compare/v2.13.0...v2.14.0)
### Added
- `toBeUppercase()`, `toBeLowercase()`, `toBeAlphaNumeric()`, `toBeAlpha()` ([#906](https://github.com/pestphp/pest/pull/906))
## [v2.13.0 (2023-08-09)](https://github.com/pestphp/pest/compare/v2.12.2...v2.13.0)
### Added
- `expect()->ddWhen` and `expect()->ddUnless` ([306b7eb](https://github.com/pestphp/pest/commit/306b7eb2a6a57e570d58228b46501ad9ba4062b4))
## [v2.12.2 (2023-08-07)](https://github.com/pestphp/pest/compare/v2.12.0...v2.12.2)
### Fixed
- Running tests from `uses` parent class ([#898](https://github.com/pestphp/pest/pull/898))
## [v2.12.0 (2023-08-02)](https://github.com/pestphp/pest/compare/v2.11.0...v2.12.0)
### Added
- Allows multiple `toMatchSnapshot` per test ([#881](https://github.com/pestphp/pest/pull/881))
### Changed
- Bumps PHPUnit to `^10.2.7` ([43107c1](https://github.com/pestphp/pest/commit/43107c17436e41e23018ae31705c688168c14784))
## [v2.11.0 (2023-08-01)](https://github.com/pestphp/pest/compare/v2.10.1...v2.11.0)
### Added
- `toBeInvokable`expectation ([#891](https://github.com/pestphp/pest/pull/891))
## [v2.10.1 (2023-07-31)](https://github.com/pestphp/pest/compare/v2.10.0...v2.10.1)
### Fixed
- `not->toHaveSuffix` and `toHavePrefix` expectations ([#888](https://github.com/pestphp/pest/pull/888))
## [v2.10.0 (2023-07-31)](https://github.com/pestphp/pest/compare/v2.9.5...v2.10.0)
### Added
- `repeat` feature ([f3f35a2](https://github.com/pestphp/pest/commit/f3f35a2ed119f63eefd323a8c66d3387e908df3f))
### Fixed
- `-v` option ([86a6b32](https://github.com/pestphp/pest/commit/86a6b3271518742dc39761228687a5107551d279))
## [v2.9.5 (2023-07-22)](https://github.com/pestphp/pest/compare/v2.9.4...v2.9.5)
### Fixed
- Assertions count on arch expectations ([632ffc2](https://github.com/pestphp/pest/commit/632ffc2f8e1fe45f739b12b818426ae14700079e))
## [v2.9.4 (2023-07-22)](https://github.com/pestphp/pest/compare/v2.9.3...v2.9.4)
### Fixed
- Output on `describe` `beforeEach` failure ([5637dfa](https://github.com/pestphp/pest/commit/5637dfa75d1a331adc810935536cde7c3196af06))
## [v2.9.3 (2023-07-20)](https://github.com/pestphp/pest/compare/v2.9.2...v2.9.3)
### Fixed
- Snapshots directory on Windows environments ([cf52752](https://github.com/pestphp/pest/commit/cf5275293fe693ec2cf4dbadbadae01daaa08169))
## [v2.9.2 (2023-07-20)](https://github.com/pestphp/pest/compare/v2.9.1...v2.9.2)
### Fixed
- `beforeEach` on Windows environments ([a37a3b9](https://github.com/pestphp/pest/commit/a37a3b9f9931bc1ab1ea9e1d6d38dfb55dde3f74))
## [v2.9.1 (2023-07-20)](https://github.com/pestphp/pest/compare/v2.9.0...v2.9.1)
### Chore
- Bumps PHPUnit to `^10.2.6` ([8fdb0b3](https://github.com/pestphp/pest/commit/8fdb0b3d32ce9ee12bd182f22751c2b41a53e97b))
## [v2.9.0 (2023-07-19)](https://github.com/pestphp/pest/compare/v2.8.1...v2.9.0)
> "Spicy Summer" is the codename assigned to Pest 2.9, for full details check our announcement: [https://pestphp.com/docs/pest-spicy-summer-release](https://pestphp.com/docs/pest-spicy-summer-release)
### Added
- Built-in Snapshot Testing ([c828756](https://github.com/pestphp/pest/commit/c8287567eb8c3dbea5845b2a6f70804b094b4b60))
- Describe Blocks ([c828756](https://github.com/pestphp/pest/commit/c8287567eb8c3dbea5845b2a6f70804b094b4b60))
- Architectural Testing++ ([c828756](https://github.com/pestphp/pest/commit/c8287567eb8c3dbea5845b2a6f70804b094b4b60))
- Type Coverage Plugin ([c828756](https://github.com/pestphp/pest/commit/c8287567eb8c3dbea5845b2a6f70804b094b4b60))
- Drift Plugin ([c828756](https://github.com/pestphp/pest/commit/c8287567eb8c3dbea5845b2a6f70804b094b4b60))
## [v2.8.1 (2023-06-20)](https://github.com/pestphp/pest/compare/v2.8.0...v2.8.1)
### Fixed
- Fixes "Cannot find TestCase object on call stack" ([eb7bb34](https://github.com/pestphp/pest/commit/eb7bb348253f412e806a6ba6f0df46c0435d0dfe))
## [v2.8.0 (2023-06-19)](https://github.com/pestphp/pest/compare/v2.7.0...v2.8.0)
### Added
- Support for `globs` in `uses` ([#829](https://github.com/pestphp/pest/pull/829))
## [v2.7.0 (2023-06-15)](https://github.com/pestphp/pest/compare/v2.6.3...v2.7.0)
### Added
- Support for unexpected output on printer ([eb9f31e](https://github.com/pestphp/pest/commit/eb9f31edeb00a88c449874f3d48156128a00fff8))
### Chore
- Bumps PHPUnit to `^10.2.2` ([0e5470b](https://github.com/pestphp/pest/commit/0e5470b192b259ba2db7c02a50371216c98fc0a6))
## [v2.6.3 (2023-06-07)](https://github.com/pestphp/pest/compare/v2.6.2...v2.6.3)
### Chore
- Bumps PHPUnit to `^10.2.1` ([73a859e](https://github.com/pestphp/pest/commit/73a859ee563fe96944ba39b191dceca28ef703c2))
## [v2.6.2 (2023-06-02)](https://github.com/pestphp/pest/compare/v2.6.1...v2.6.2)
### Chore
- Bumps PHPUnit to `^10.2.0` ([a0041f1](https://github.com/pestphp/pest/commit/a0041f139cba94fe5d15318c38e275f2e2fb3350))
## [v2.6.1 (2023-04-12)](https://github.com/pestphp/pest/compare/v2.6.0...v2.6.1)
### Fixes
- PHPStorm issue output problem for tests throwing an exception before the first assertion ([#809](https://github.com/pestphp/pest/pull/809))
- Allow traits to be covered ([#804](https://github.com/pestphp/pest/pull/804))
### Chore
- Bumps PHPUnit to `^10.1.3` ([c993252](https://github.com/pestphp/pest/commit/c99325275acf1fd3759b487b93ec50473f706709))
## [v2.6.0 (2023-04-05)](https://github.com/pestphp/pest/compare/v2.5.2...v2.6.0)
### Adds
- Allows `toThrow` to be used against an exception instance ([#797](https://github.com/pestphp/pest/pull/797))
## [v2.5.2 (2023-04-19)](https://github.com/pestphp/pest/compare/v2.5.1...v2.5.2)
### Chore
- Removes `myclabs/php-enuma` dependency ([1a05df1](https://github.com/pestphp/pest/commit/1a05df14d0ce7d12583df26ff716807db6f81f13))
## [v2.5.1 (2023-04-18)](https://github.com/pestphp/pest/compare/v2.5.0...v2.5.1)
### Chore
- Bumps PHPUnit to `^10.1.1` ([ec6a817](https://github.com/pestphp/pest/commit/ec6a81735af19f5463d24545df97535d77697ec6))
## [v2.5.0 (2023-04-14)](https://github.com/pestphp/pest/compare/v2.4.0...v2.5.0)
### Chore
- Bumps PHPUnit to `^10.1.0` ([#780](https://github.com/pestphp/pest/pull/780))
## [v2.4.0 (2023-04-03)](https://github.com/pestphp/pest/compare/v2.3.0...v2.4.0)
### Added
- `skipOnWindows()`, `skipOnMac()`, and `skipOnLinux()` ([#757](https://github.com/pestphp/pest/pull/757))
- source architecture testing violation ([#1](https://github.com/pestphp/pest-plugin-arch/pull/1))([8e66263](https://github.com/pestphp/pest-plugin-arch/commit/8e66263104304e99e3d6ceda25c7ed679b27fb03))
- `toHaveProperties` may now also check values ([#760](https://github.com/pestphp/pest/pull/760))
### Fixed
- Tests on `tests/Helpers` directory not being executed ([#753](https://github.com/pestphp/pest/pull/753))
- Teamcity count ([#747](https://github.com/pestphp/pest/pull/747))
- Parallel execution when class extends class with same name ([#748](https://github.com/pestphp/pest/pull/748))
- Wording on `uses()` hint ([#745](https://github.com/pestphp/pest/pull/745/files))
## [v2.3.0 (2023-03-28)](https://github.com/pestphp/pest/compare/v2.2.3...v2.3.0)
### Added
- Better error handler about missing uses ([#743](https://github.com/pestphp/pest/pull/743))
### Fixed
- Inconsistent spelling of `dataset` ([#739](https://github.com/pestphp/pest/pull/739))
### Chore
- Bumps PHPUnit to `^10.0.19` ([3d7e621](https://github.com/pestphp/pest/commit/3d7e621b7dfc03f0b2d9dcf6eb06c26bc383f502))
## [v2.2.3 (2023-03-24)](https://github.com/pestphp/pest/compare/v2.2.2...v2.2.3)
### Fixed
- Unnecessary dataset on dataset arguments mismatch ([#736](https://github.com/pestphp/pest/pull/736))
- Parallel arguments on plugins order ([#703](https://github.com/pestphp/pest/pull/703))
- Arch plugin runtime exceptions on bad phpdocs ([2f2b51c](https://github.com/pestphp/pest/commit/2f2b51ce3d1b000be9d6add0e785fd0044931b3b))
## [v2.2.2 (2023-03-23)](https://github.com/pestphp/pest/compare/v2.2.1...v2.2.2)
### Fixed
- Edge case in parallel execution test description ([3ce6408](https://github.com/pestphp/pest/commit/3ce640819541ca6022b250e000f336d87c3e7889))
## [v2.2.1 (2023-03-22)](https://github.com/pestphp/pest/compare/v2.2.0...v2.2.1)
### Fixed
- Collision between tests names with underscores ([#724](https://github.com/pestphp/pest/pull/724))
### Chore
- Bumps PHPUnit to `^10.0.18` ([1408cff](https://github.com/pestphp/pest/commit/1408cffc028690057e44f00038f9390f776e6bfb))
## [v2.2.0 (2023-03-22)](https://github.com/pestphp/pest/compare/v2.1.0...v2.2.0)
### Added
- Improved error messages on dataset arguments mismatch ([#698](https://github.com/pestphp/pest/pull/698))
- Allows the usage of `DateTimeInterface` on multiple expectations ([#716](https://github.com/pestphp/pest/pull/716))
### Fixed
- `--dirty` option on Windows environments ([#721](https://github.com/pestphp/pest/pull/721))
- Parallel exit code when `phpunit.xml` is outdated ([14dd5cb](https://github.com/pestphp/pest/commit/14dd5cb57b9432300ac4e8095f069941cb43bdb5))
## [v2.1.0 (2023-03-21)](https://github.com/pestphp/pest/compare/v2.0.2...v2.1.0)
### Added
- `only` test case method ([bcd1503](https://github.com/pestphp/pest/commit/bcd1503cade938853a55c1283b02b6b820ea0b69))
### Fixed
- Issues with different characters on test names ([715](https://github.com/pestphp/pest/pull/715))
## [v2.0.2 (2023-03-20)](https://github.com/pestphp/pest/compare/v2.0.1...v2.0.2)
### Fixed
- `Pest.php` not being loaded in certain scenarios ([b887116](https://github.com/pestphp/pest/commit/b887116e5ce9a69403ad620cad20f0a029474eb5))
## [v2.0.1 (2023-03-20)](https://github.com/pestphp/pest/compare/v2.0.0...v2.0.1)
### Fixed
- Wrong `version` configuration key on `composer.json` ([8f91f40](https://github.com/pestphp/pest/commit/8f91f40e8ea8b35e04b7989bed6a8f9439e2a2d6))
## [v2.0.0 (2023-03-20)](https://github.com/pestphp/pest/compare/v1.22.6...v2.0.0)
Please consult the [upgrade guide](https://pestphp.com/docs/upgrade-guide) and [release notes](https://pestphp.com/docs/announcing-pest2) in the official Pest documentation.

View File

@ -5,10 +5,10 @@ When releasing a new version of Pest there are some checks and updates that need
> **For Pest v1 you should use the `1.x` branch instead.** > **For Pest v1 you should use the `1.x` branch instead.**
- Clear your local repository with: `git add . && git reset --hard && git checkout 2.x` - Clear your local repository with: `git add . && git reset --hard && git checkout 2.x`
- On the GitHub repository, check the contents of [github.com/pestphp/pest/compare/{latest_version}...2.x](https://github.com/pestphp/pest/compare/{latest_version}...master) and update the [changelog](CHANGELOG.md) file with the main changes for this release - On the GitHub repository, check the contents of [github.com/pestphp/pest/compare/{latest_version}...2.x](https://github.com/pestphp/pest/compare/{latest_version}...2.x)
- Update the version number in [src/Pest.php](src/Pest.php) - Update the version number in [src/Pest.php](src/Pest.php)
- Run the tests locally using: `composer test` - Run the tests locally using: `composer test`
- Commit the CHANGELOG and Pest file with the message: `git commit -m "release: vX.X.X"` - Commit the Pest file with the message: `git commit -m "release: vX.X.X"`
- Push the changes to GitHub - Push the changes to GitHub
- Check that the CI is passing as expected: [github.com/pestphp/pest/actions](https://github.com/pestphp/pest/actions) - 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` - Tag and push the tag with `git tag vX.X.X && git push --tags`

View File

@ -18,16 +18,17 @@
], ],
"require": { "require": {
"php": "^8.1.0", "php": "^8.1.0",
"brianium/paratest": "^7.2.6", "brianium/paratest": "^7.2.9",
"nunomaduro/collision": "^7.8.1", "nunomaduro/collision": "^7.9.0|^8.0.0",
"nunomaduro/termwind": "^1.15.1", "nunomaduro/termwind": "^1.15.1|^2.0.0",
"pestphp/pest-plugin": "^2.1.1", "pestphp/pest-plugin": "^2.1.1",
"pestphp/pest-plugin-arch": "^2.3.3", "pestphp/pest-plugin-arch": "^2.4.0",
"phpunit/phpunit": "^10.3.2" "phpunit/phpunit": "^10.4.1"
}, },
"conflict": { "conflict": {
"webmozart/assert": "<1.11.0", "phpunit/phpunit": ">10.4.1",
"phpunit/phpunit": ">10.3.2" "sebastian/exporter": "<5.1.0",
"webmozart/assert": "<1.11.0"
}, },
"autoload": { "autoload": {
"psr-4": { "psr-4": {
@ -51,7 +52,7 @@
}, },
"require-dev": { "require-dev": {
"pestphp/pest-dev-tools": "^2.16.0", "pestphp/pest-dev-tools": "^2.16.0",
"pestphp/pest-plugin-type-coverage": "^2.2.0", "pestphp/pest-plugin-type-coverage": "^2.4.0",
"symfony/process": "^6.3.4" "symfony/process": "^6.3.4"
}, },
"minimum-stability": "dev", "minimum-stability": "dev",

View File

@ -132,7 +132,7 @@ final class TestSuiteLoader
continue; continue;
} }
if ($class->isAbstract() || ($class->getFileName() !== $suiteClassFile)) { if ($class->isAbstract() || ($suiteClassFile !== $class->getFileName())) {
if (! str_contains($class->getFileName(), 'TestCaseFactory.php')) { if (! str_contains($class->getFileName(), 'TestCaseFactory.php')) {
continue; continue;
} }

View File

@ -239,7 +239,7 @@ final class Expectation
$index = isset($callbacks[$index + 1]) ? $index + 1 : 0; $index = isset($callbacks[$index + 1]) ? $index + 1 : 0;
} }
if (count($callbacks) > $valuesCount) { if ($valuesCount < count($callbacks)) {
throw new OutOfRangeException('Sequence expectations are more than the iterable items.'); throw new OutOfRangeException('Sequence expectations are more than the iterable items.');
} }
@ -862,4 +862,20 @@ final class Expectation
FileLineFinder::where(fn (string $line): bool => str_contains($line, 'class')), FileLineFinder::where(fn (string $line): bool => str_contains($line, 'class')),
); );
} }
/**
* Asserts that the given expectation target has a constructor method.
*/
public function toHaveConstructor(): ArchExpectation
{
return $this->toHaveMethod('__construct');
}
/**
* Asserts that the given expectation target has a destructor method.
*/
public function toHaveDestructor(): ArchExpectation
{
return $this->toHaveMethod('__destruct');
}
} }

View File

@ -185,7 +185,7 @@ final class OppositeExpectation
} }
/** /**
* Asserts that the given expectation targets is an class. * Asserts that the given expectation targets is not class.
*/ */
public function toBeClass(): ArchExpectation public function toBeClass(): ArchExpectation
{ {
@ -227,7 +227,7 @@ final class OppositeExpectation
} }
/** /**
* Asserts that the given expectation target to be subclass of the given class. * Asserts that the given expectation target to be not subclass of the given class.
* *
* @param class-string $class * @param class-string $class
*/ */
@ -469,4 +469,20 @@ final class OppositeExpectation
implode(' ', array_map(fn (mixed $argument): string => $toString($argument), $arguments)), implode(' ', array_map(fn (mixed $argument): string => $toString($argument), $arguments)),
)); ));
} }
/**
* Asserts that the given expectation target does not have a constructor method.
*/
public function toHaveConstructor(): ArchExpectation
{
return $this->toHaveMethod('__construct');
}
/**
* Asserts that the given expectation target does not have a destructor method.
*/
public function toHaveDestructor(): ArchExpectation
{
return $this->toHaveMethod('__destruct');
}
} }

View File

@ -19,7 +19,7 @@ final class Depends implements AddsAnnotations
public function __invoke(TestCaseMethodFactory $method, array $annotations): array public function __invoke(TestCaseMethodFactory $method, array $annotations): array
{ {
foreach ($method->depends as $depend) { foreach ($method->depends as $depend) {
$depend = Str::evaluable($depend); $depend = Str::evaluable($method->describing !== null ? Str::describe($method->describing, $depend) : $depend);
$annotations[] = "@depends $depend"; $annotations[] = "@depends $depend";
} }

View File

@ -142,7 +142,7 @@ final class TestCaseFactory
$namespace = implode('\\', $partsFQN); $namespace = implode('\\', $partsFQN);
$baseClass = sprintf('\%s', $this->class); $baseClass = sprintf('\%s', $this->class);
if ('' === trim($className)) { if (trim($className) === '') {
$className = 'InvalidTestName'.Str::random(); $className = 'InvalidTestName'.Str::random();
} }
@ -241,7 +241,7 @@ final class TestCaseFactory
throw ShouldNotHappen::fromMessage('The test description may not be empty.'); throw ShouldNotHappen::fromMessage('The test description may not be empty.');
} }
if (Str::evaluable($method->description) === $methodName) { if ($methodName === Str::evaluable($method->description)) {
return true; return true;
} }
} }
@ -259,7 +259,7 @@ final class TestCaseFactory
throw ShouldNotHappen::fromMessage('The test description may not be empty.'); throw ShouldNotHappen::fromMessage('The test description may not be empty.');
} }
if (Str::evaluable($method->description) === $methodName) { if ($methodName === Str::evaluable($method->description)) {
return $method; return $method;
} }
} }

View File

@ -16,6 +16,7 @@ use Pest\Matchers\Any;
use Pest\Support\Arr; use Pest\Support\Arr;
use Pest\Support\Exporter; use Pest\Support\Exporter;
use Pest\Support\NullClosure; use Pest\Support\NullClosure;
use Pest\Support\Str;
use Pest\TestSuite; use Pest\TestSuite;
use PHPUnit\Framework\Assert; use PHPUnit\Framework\Assert;
use PHPUnit\Framework\Constraint\Constraint; use PHPUnit\Framework\Constraint\Constraint;
@ -926,7 +927,7 @@ final class Expectation
$callback = $exception; $callback = $exception;
$parameters = (new ReflectionFunction($exception))->getParameters(); $parameters = (new ReflectionFunction($exception))->getParameters();
if (1 !== count($parameters)) { if (count($parameters) !== 1) {
throw new InvalidArgumentException('The given closure must have a single parameter type-hinted as the class string.'); throw new InvalidArgumentException('The given closure must have a single parameter type-hinted as the class string.');
} }
@ -950,7 +951,7 @@ final class Expectation
} }
if (! class_exists($exception)) { if (! class_exists($exception)) {
if ($e instanceof Error && $e->getMessage() === "Class \"$exception\" not found") { if ($e instanceof Error && "Class \"$exception\" not found" === $e->getMessage()) {
Assert::assertTrue(true); Assert::assertTrue(true);
throw $e; throw $e;
@ -966,6 +967,7 @@ final class Expectation
} }
Assert::assertInstanceOf($exception, $e, $message); Assert::assertInstanceOf($exception, $e, $message);
$callback($e); $callback($e);
return $this; return $this;
@ -1111,4 +1113,49 @@ final class Expectation
return $this; return $this;
} }
/**
* Asserts that the value is UUID.
*
* @return self<TValue>
*/
public function toBeUuid(string $message = ''): self
{
if (! is_string($this->value)) {
InvalidExpectationValue::expected('string');
}
Assert::assertTrue(Str::isUuid($this->value), $message);
return $this;
}
/**
* Asserts that the value is between 2 specified values
*
* @return self<TValue>
*/
public function toBeBetween(int|float|DateTimeInterface $lowestValue, int|float|DateTimeInterface $highestValue, string $message = ''): self
{
Assert::assertGreaterThanOrEqual($lowestValue, $this->value, $message);
Assert::assertLessThanOrEqual($highestValue, $this->value, $message);
return $this;
}
/**
* Asserts that the value is a url
*
* @return self<TValue>
*/
public function toBeUrl(string $message = ''): self
{
if ($message === '') {
$message = "Failed asserting that {$this->value} is a url.";
}
Assert::assertTrue(Str::isUrl((string) $this->value), $message);
return $this;
}
} }

View File

@ -16,6 +16,7 @@ use Pest\Support\Backtrace;
use Pest\Support\Exporter; use Pest\Support\Exporter;
use Pest\Support\HigherOrderCallables; use Pest\Support\HigherOrderCallables;
use Pest\Support\NullClosure; use Pest\Support\NullClosure;
use Pest\Support\Str;
use Pest\TestSuite; use Pest\TestSuite;
use PHPUnit\Framework\TestCase; use PHPUnit\Framework\TestCase;
@ -209,7 +210,7 @@ final class TestCall
*/ */
private function skipOn(string $osFamily, string $message): self private function skipOn(string $osFamily, string $message): self
{ {
return PHP_OS_FAMILY === $osFamily return $osFamily === PHP_OS_FAMILY
? $this->skip($message) ? $this->skip($message)
: $this; : $this;
} }
@ -361,7 +362,7 @@ final class TestCall
{ {
if (! is_null($this->describing)) { if (! is_null($this->describing)) {
$this->testCaseMethod->describing = $this->describing; $this->testCaseMethod->describing = $this->describing;
$this->testCaseMethod->description = sprintf('`%s` → %s', $this->describing, $this->testCaseMethod->description); $this->testCaseMethod->description = Str::describe($this->describing, $this->testCaseMethod->description); // @phpstan-ignore-line
} }
$this->testSuite->tests->set($this->testCaseMethod); $this->testSuite->tests->set($this->testCaseMethod);

View File

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

View File

@ -254,11 +254,11 @@ final class WrapperRunner implements RunnerInterface
private function destroyWorker(int $token): void private function destroyWorker(int $token): void
{ {
// Mutation Testing tells us that the following `unset()` already destroys
// the `WrapperWorker`, which destroys the Symfony's `Process`, which
// automatically calls `Process::stop` within `Process::__destruct()`.
// But we prefer to have an explicit stops.
$this->workers[$token]->stop(); $this->workers[$token]->stop();
// We need to wait for ApplicationForWrapperWorker::end to end
while ($this->workers[$token]->isRunning()) {
usleep(self::CYCLE_SLEEP);
}
unset($this->workers[$token]); unset($this->workers[$token]);
} }
@ -297,6 +297,7 @@ final class WrapperRunner implements RunnerInterface
array_merge_recursive($testResultSum->phpDeprecations(), $testResult->phpDeprecations()), array_merge_recursive($testResultSum->phpDeprecations(), $testResult->phpDeprecations()),
array_merge_recursive($testResultSum->phpNotices(), $testResult->phpNotices()), array_merge_recursive($testResultSum->phpNotices(), $testResult->phpNotices()),
array_merge_recursive($testResultSum->phpWarnings(), $testResult->phpWarnings()), array_merge_recursive($testResultSum->phpWarnings(), $testResult->phpWarnings()),
$testResultSum->numberOfIssuesIgnoredByBaseline() + $testResult->numberOfIssuesIgnoredByBaseline(),
); );
} }
@ -325,6 +326,8 @@ final class WrapperRunner implements RunnerInterface
$testResultSum->phpDeprecations(), $testResultSum->phpDeprecations(),
$testResultSum->phpNotices(), $testResultSum->phpNotices(),
$testResultSum->phpWarnings(), $testResultSum->phpWarnings(),
$testResultSum->numberOfIssuesIgnoredByBaseline(),
); );
$this->printer->printResults( $this->printer->printResults(

View File

@ -51,7 +51,7 @@ final class Str
return true; return true;
} }
return substr($target, -$length) === $search; return $search === substr($target, -$length);
} }
/** /**
@ -92,4 +92,28 @@ final class Str
{ {
return $search === '' ? $subject : array_reverse(explode($search, $subject, 2))[0]; return $search === '' ? $subject : array_reverse(explode($search, $subject, 2))[0];
} }
/**
* Determine if a given value is a valid UUID.
*/
public static function isUuid(string $value): bool
{
return preg_match('/^[\da-f]{8}-[\da-f]{4}-[\da-f]{4}-[\da-f]{4}-[\da-f]{12}$/iD', $value) > 0;
}
/**
* Creates a describe block as `$describeDescription` → `$testDescription` format.
*/
public static function describe(string $describeDescription, string $testDescription): string
{
return sprintf('`%s` → %s', $describeDescription, $testDescription);
}
/**
* Determine if a given value is a valid URL.
*/
public static function isUrl(string $value): bool
{
return (bool) filter_var($value, FILTER_VALIDATE_URL);
}
} }

View File

@ -12,11 +12,6 @@
<directory suffix="Test.php">./tests/Feature</directory> <directory suffix="Test.php">./tests/Feature</directory>
</testsuite> </testsuite>
</testsuites> </testsuites>
<coverage>
<include>
<directory suffix=".php">./app</directory>
</include>
</coverage>
<php> <php>
<env name="APP_ENV" value="testing"/> <env name="APP_ENV" value="testing"/>
<env name="BCRYPT_ROUNDS" value="4"/> <env name="BCRYPT_ROUNDS" value="4"/>
@ -28,4 +23,9 @@
<env name="SESSION_DRIVER" value="array"/> <env name="SESSION_DRIVER" value="array"/>
<env name="TELESCOPE_ENABLED" value="false"/> <env name="TELESCOPE_ENABLED" value="false"/>
</php> </php>
<source>
<include>
<directory suffix=".php">./app</directory>
</include>
</source>
</phpunit> </phpunit>

View File

@ -9,10 +9,10 @@
<directory suffix="Test.php">./tests</directory> <directory suffix="Test.php">./tests</directory>
</testsuite> </testsuite>
</testsuites> </testsuites>
<coverage> <source>
<include> <include>
<directory suffix=".php">./app</directory> <directory suffix=".php">./app</directory>
<directory suffix=".php">./src</directory> <directory suffix=".php">./src</directory>
</include> </include>
</coverage> </source>
</phpunit> </phpunit>

View File

@ -1,5 +1,5 @@
Pest Testing Framework 2.17.0. Pest Testing Framework 2.23.1.
USAGE: pest <file> [options] USAGE: pest <file> [options]
@ -14,6 +14,9 @@
--cache-directory [dir] ............................ Specify cache directory --cache-directory [dir] ............................ Specify cache directory
--generate-configuration Generate configuration file with suggested settings --generate-configuration Generate configuration file with suggested settings
--migrate-configuration ....... Migrate configuration file to current format --migrate-configuration ....... Migrate configuration file to current format
--generate-baseline [file] .................... Generate baseline for issues
--use-baseline [file] ........................ Use baseline to ignore issues
--ignore-baseline ..................... Do not use baseline to ignore issues
SELECTION OPTIONS: SELECTION OPTIONS:
--bail ........................... Stop execution upon first not-passed test --bail ........................... Stop execution upon first not-passed test
@ -89,7 +92,7 @@
--testdox-html [file] .. Write test results in TestDox format (HTML) to file --testdox-html [file] .. Write test results in TestDox format (HTML) to file
--testdox-text [file] Write test results in TestDox format (plain text) to file --testdox-text [file] Write test results in TestDox format (plain text) to file
--log-events-text [file] ............... Stream events as plain text to file --log-events-text [file] ............... Stream events as plain text to file
--log-events-verbose-text [file] Stream events as plain text (with telemetry information) to file --log-events-verbose-text [file] Stream events as plain text with extended information to file
--no-logging ....... Ignore logging configured in the XML configuration file --no-logging ....... Ignore logging configured in the XML configuration file
CODE COVERAGE OPTIONS: CODE COVERAGE OPTIONS:

View File

@ -1,3 +1,3 @@
Pest Testing Framework 2.17.0. Pest Testing Framework 2.23.1.

View File

@ -187,6 +187,10 @@
✓ with with (1) ✓ with with (1)
✓ with on hook → value with (2) ✓ with on hook → value with (2)
✓ with on describe → value with (3) ✓ with on describe → value with (3)
✓ depends on describe → foo
✓ depends on describe → bar
✓ depends on describe using with → foo with (3)
✓ depends on describe using with → bar with (3)
PASS Tests\Features\DescriptionLess PASS Tests\Features\DescriptionLess
✓ get 'foo' ✓ get 'foo'
@ -328,6 +332,18 @@
✓ pass ✓ pass
✓ failures ✓ failures
✓ failures with custom message ✓ failures with custom message
✓ not failures
PASS Tests\Features\Expect\toBeBetween
✓ passes with int
✓ passes with float
✓ passes with float and int
✓ passes with DateTime
✓ failure with int
✓ failure with float
✓ failure with float and int
✓ failure with DateTime
✓ failures with custom message
✓ not failures ✓ not failures
PASS Tests\Features\Expect\toBeBool PASS Tests\Features\Expect\toBeBool
@ -574,6 +590,20 @@
✓ pass ✓ pass
✓ failures ✓ failures
✓ failures with custom message ✓ failures with custom message
✓ not failures
PASS Tests\Features\Expect\toBeUrl
✓ pass
✓ failures
✓ failures with custom message
✓ failures with default message
✓ not failures
PASS Tests\Features\Expect\toBeUuid
✓ failures with wrong type
✓ pass
✓ failures
✓ failures with message
✓ not failures ✓ not failures
PASS Tests\Features\Expect\toBeWritableDirectory PASS Tests\Features\Expect\toBeWritableDirectory
@ -641,6 +671,10 @@
✓ failures with message ✓ failures with message
✓ not failures ✓ not failures
PASS Tests\Features\Expect\toHaveConstructor
✓ class has constructor
✓ class has no constructor
PASS Tests\Features\Expect\toHaveCount PASS Tests\Features\Expect\toHaveCount
✓ pass ✓ pass
✓ failures with invalid type ✓ failures with invalid type
@ -648,6 +682,10 @@
✓ failures with message ✓ failures with message
✓ not failures ✓ not failures
PASS Tests\Features\Expect\toHaveDestructor
✓ class has destructor
✓ class has no destructor
PASS Tests\Features\Expect\toHaveKebabCaseKeys PASS Tests\Features\Expect\toHaveKebabCaseKeys
✓ pass ✓ pass
✓ failures ✓ failures
@ -1314,4 +1352,4 @@
WARN Tests\Visual\Version WARN Tests\Visual\Version
- visual snapshot of help command output - visual snapshot of help command output
Tests: 2 deprecated, 4 warnings, 5 incomplete, 2 notices, 13 todos, 19 skipped, 930 passed (2200 assertions) Tests: 2 deprecated, 4 warnings, 5 incomplete, 2 notices, 13 todos, 19 skipped, 958 passed (2281 assertions)

View File

@ -76,3 +76,23 @@ describe('with on describe', function () {
expect($foo)->toBe(3); expect($foo)->toBe(3);
}); });
})->with([3]); })->with([3]);
describe('depends on describe', function () {
test('foo', function () {
expect('foo')->toBe('foo');
});
test('bar', function () {
expect('bar')->toBe('bar');
})->depends('foo');
});
describe('depends on describe using with', function () {
test('foo', function ($foo) {
expect($foo)->toBe(3);
});
test('bar', function ($foo) {
expect($foo + $foo)->toBe(6);
})->depends('foo');
})->with([3]);

View File

@ -0,0 +1,43 @@
<?php
use PHPUnit\Framework\ExpectationFailedException;
test('passes with int', function () {
expect(2)->toBeBetween(1, 3);
});
test('passes with float', function () {
expect(1.5)->toBeBetween(1.25, 1.75);
});
test('passes with float and int', function () {
expect(1.5)->toBeBetween(1, 2);
});
test('passes with DateTime', function () {
expect(new DateTime('2023-09-22'))->toBeBetween(new DateTime('2023-09-21'), new DateTime('2023-09-23'));
});
test('failure with int', function () {
expect(4)->toBeBetween(1, 3);
})->throws(ExpectationFailedException::class);
test('failure with float', function () {
expect(2)->toBeBetween(1.5, 1.75);
})->throws(ExpectationFailedException::class);
test('failure with float and int', function () {
expect(2.1)->toBeBetween(1, 2);
})->throws(ExpectationFailedException::class);
test('failure with DateTime', function () {
expect(new DateTime('2023-09-20'))->toBeBetween(new DateTime('2023-09-21'), new DateTime('2023-09-23'));
})->throws(ExpectationFailedException::class);
test('failures with custom message', function () {
expect(4)->toBeBetween(1, 3, 'oh no!');
})->throws(ExpectationFailedException::class, 'oh no!');
test('not failures', function () {
expect(2)->not->toBeBetween(1, 3);
})->throws(ExpectationFailedException::class);

View File

@ -0,0 +1,24 @@
<?php
use PHPUnit\Framework\ExpectationFailedException;
test('pass', function () {
expect('https://pestphp.com')->toBeUrl()
->and('pestphp.com')->not->toBeUrl();
});
test('failures', function () {
expect('pestphp.com')->toBeUrl();
})->throws(ExpectationFailedException::class);
test('failures with custom message', function () {
expect('pestphp.com')->toBeUrl('oh no!');
})->throws(ExpectationFailedException::class, 'oh no!');
test('failures with default message', function () {
expect('pestphp.com')->toBeUrl();
})->throws(ExpectationFailedException::class, 'Failed asserting that pestphp.com is a url.');
test('not failures', function () {
expect('https://pestphp.com')->not->toBeUrl();
})->throws(ExpectationFailedException::class);

View File

@ -0,0 +1,31 @@
<?php
use Pest\Exceptions\InvalidExpectationValue;
use PHPUnit\Framework\ExpectationFailedException;
test('failures with wrong type', function () {
expect([])->toBeUuid();
})->throws(InvalidExpectationValue::class, 'Invalid expectation value type. Expected [string].');
test('pass', function () {
expect('3cafb226-4326-11ee-a516-846993788c86')->toBeUuid(); // version 1
expect('0000415c-4326-21ee-a700-846993788c86')->toBeUuid(); // version 2
expect('3f703955-aaba-3e70-a3cb-baff6aa3b28f')->toBeUuid(); // version 3
expect('ca0a8228-cdf6-41db-b34b-c2f31485796c')->toBeUuid(); // version 4
expect('a35477ae-bfb1-5f2e-b5a4-4711594d855f')->toBeUuid(); // version 5
expect('1ee43263-cf5a-6fd8-8f47-846993788c86')->toBeUuid(); // version 6
expect('018a2bef-09f2-728c-becb-c3f569d91486')->toBeUuid(); // version 7
expect('00112233-4455-8677-8899-aabbccddeeff')->toBeUuid(); // version 8
});
test('failures', function () {
expect('foo')->toBeUuid();
})->throws(ExpectationFailedException::class);
test('failures with message', function () {
expect('bar')->toBeUuid('oh no!');
})->throws(ExpectationFailedException::class, 'oh no!');
test('not failures', function () {
expect('foo')->not->toBeUuid();
});

View File

@ -0,0 +1,9 @@
<?php
test('class has constructor')
->expect('Tests\Fixtures\Arch\ToHaveConstructor\HasConstructor\HasConstructor')
->toHaveConstructor();
test('class has no constructor')
->expect('Tests\Fixtures\Arch\ToHaveConstructor\HasNoConstructor\HasNoConstructor')
->not->toHaveConstructor();

View File

@ -0,0 +1,9 @@
<?php
test('class has destructor')
->expect('Tests\Fixtures\Arch\ToHaveDestructor\HasDestructor\HasDestructor')
->toHaveDestructor();
test('class has no destructor')
->expect('Tests\Fixtures\Arch\ToHaveDestructor\HasNoDestructor\HasNoDestructor')
->not->toHaveDestructor();

View File

@ -62,15 +62,15 @@ test('fails with wrong value and plain key with dots', function () use ($test_ar
test('not failures', function () use ($test_array) { test('not failures', function () use ($test_array) {
expect($test_array)->not->toHaveKey('c'); expect($test_array)->not->toHaveKey('c');
})->throws(ExpectationFailedException::class, "Expecting Array (…) not to have key 'c'"); })->throws(ExpectationFailedException::class, "Expecting […] not to have key 'c'");
test('not failures with nested key', function () use ($test_array) { test('not failures with nested key', function () use ($test_array) {
expect($test_array)->not->toHaveKey('d.e'); expect($test_array)->not->toHaveKey('d.e');
})->throws(ExpectationFailedException::class, "Expecting Array (…) not to have key 'd.e'"); })->throws(ExpectationFailedException::class, "Expecting […] not to have key 'd.e'");
test('not failures with plain key with dots', function () use ($test_array) { test('not failures with plain key with dots', function () use ($test_array) {
expect($test_array)->not->toHaveKey('key.with.dots'); expect($test_array)->not->toHaveKey('key.with.dots');
})->throws(ExpectationFailedException::class, "Expecting Array (…) not to have key 'key.with.dots'"); })->throws(ExpectationFailedException::class, "Expecting […] not to have key 'key.with.dots'");
test('not failures with correct value', function () use ($test_array) { test('not failures with correct value', function () use ($test_array) {
expect($test_array)->not->toHaveKey('c', 'world'); expect($test_array)->not->toHaveKey('c', 'world');

View File

@ -57,8 +57,9 @@ test('failures 3', function () {
expect(function () { expect(function () {
throw new Exception(); throw new Exception();
})->toThrow(function (RuntimeException $e) { })->toThrow(function (RuntimeException $e) {
//
}); });
})->throws(ExpectationFailedException::class, 'Failed asserting that Exception Object'); })->throws(ExpectationFailedException::class, 'Failed asserting that an object is an instance of class RuntimeException.');
test('failures 4', function () { test('failures 4', function () {
expect(function () { expect(function () {
@ -73,7 +74,7 @@ test('failures 5', function () {
expect(function () { expect(function () {
throw new Exception('actual message'); throw new Exception('actual message');
})->toThrow('expected message'); })->toThrow('expected message');
})->throws(ExpectationFailedException::class, 'Failed asserting that \'actual message\' contains "expected message".'); })->throws(ExpectationFailedException::class, 'Failed asserting that \'actual message\' [ASCII](length: 14) contains "expected message" [ASCII](length: 16).');
test('failures 6', function () { test('failures 6', function () {
expect(function () { expect(function () {

View File

@ -0,0 +1,13 @@
<?php
declare(strict_types=1);
namespace Tests\Fixtures\Arch\ToHaveConstructor\HasConstructor;
class HasConstructor
{
public function __construct()
{
}
}

View File

@ -0,0 +1,9 @@
<?php
declare(strict_types=1);
namespace Tests\Fixtures\Arch\ToHaveConstructor\HasNoConstructor;
class HasNoConstructor
{
}

View File

@ -0,0 +1,13 @@
<?php
declare(strict_types=1);
namespace Tests\Fixtures\Arch\ToHaveDestructor\HasDestructor;
class HasDestructor
{
public function __destruct()
{
}
}

View File

@ -0,0 +1,9 @@
<?php
declare(strict_types=1);
namespace Tests\Fixtures\Arch\ToHaveDestructor\HasNoDestructor;
class HasNoDestructor
{
}

View File

@ -16,7 +16,7 @@ $run = function () {
test('parallel', function () use ($run) { test('parallel', function () use ($run) {
expect($run('--exclude-group=integration')) expect($run('--exclude-group=integration'))
->toContain('Tests: 1 deprecated, 4 warnings, 5 incomplete, 2 notices, 13 todos, 15 skipped, 919 passed (2185 assertions)') ->toContain('Tests: 1 deprecated, 4 warnings, 5 incomplete, 2 notices, 13 todos, 15 skipped, 947 passed (2266 assertions)')
->toContain('Parallel: 3 processes'); ->toContain('Parallel: 3 processes');
})->skipOnWindows(); })->skipOnWindows();