Skip to content

Require PHP 7.1+ and add type declarations #11

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Nov 18, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 0 additions & 5 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,6 @@ jobs:
- 7.3
- 7.2
- 7.1
- 7.0
- 5.6
- 5.5
- 5.4
- 5.3
steps:
- uses: actions/checkout@v2
- uses: shivammathur/setup-php@v2
Expand Down
12 changes: 9 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -75,8 +75,8 @@ Once the promise is fulfilled, this function will return whatever the promise
resolved to.

Once the promise is rejected, this will throw whatever the promise rejected
with. If the promise did not reject with an `Exception` or `Throwable` (PHP 7+),
then this function will throw an `UnexpectedValueException` instead.
with. If the promise did not reject with an `Exception` or `Throwable`, then
this function will throw an `UnexpectedValueException` instead.

```php
try {
Expand Down Expand Up @@ -222,9 +222,15 @@ $ composer require react/async:dev-main
See also the [CHANGELOG](CHANGELOG.md) for details about version upgrades.

This project aims to run on any platform and thus does not require any PHP
extensions and supports running on legacy PHP 5.3 through current PHP 8+.
extensions and supports running on PHP 7.1 through current PHP 8+.
It's *highly recommended to use the latest supported PHP version* for this project.

We're committed to providing long-term support (LTS) options and to provide a
smooth upgrade path. If you're using an older PHP version, you may use the
[`2.x` branch](https://github.com/reactphp/async/tree/2.x) which provides a
compatible API but does not take advantage of newer language features. You may
target both versions at the same time to support a wider range of PHP versions.

## Tests

To run the test suite, you first need to clone this repo and then install all
Expand Down
4 changes: 2 additions & 2 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -26,12 +26,12 @@
}
],
"require": {
"php": ">=5.3.2",
"php": ">=7.1",
"react/event-loop": "^1.2",
"react/promise": "^2.8 || ^1.2.1"
},
"require-dev": {
"phpunit/phpunit": "^9.3 || ^5.7 || ^4.8.35"
"phpunit/phpunit": "^9.3 || ^7.5"
},
"autoload": {
"files": [
Expand Down
2 changes: 1 addition & 1 deletion phpunit.xml.legacy
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

<!-- PHPUnit configuration file with old format for PHPUnit 9.2 or older -->
<phpunit xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="https://schema.phpunit.de/4.8/phpunit.xsd"
xsi:noNamespaceSchemaLocation="https://schema.phpunit.de/7.5/phpunit.xsd"
bootstrap="vendor/autoload.php"
colors="true">
<testsuites>
Expand Down
24 changes: 12 additions & 12 deletions src/functions.php
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,8 @@
* resolved to.
*
* Once the promise is rejected, this will throw whatever the promise rejected
* with. If the promise did not reject with an `Exception` or `Throwable` (PHP 7+),
* then this function will throw an `UnexpectedValueException` instead.
* with. If the promise did not reject with an `Exception` or `Throwable`, then
* this function will throw an `UnexpectedValueException` instead.
*
* ```php
* try {
Expand All @@ -45,7 +45,7 @@
* @param PromiseInterface $promise
* @return mixed returns whatever the promise resolves to
* @throws \Exception when the promise is rejected with an `Exception`
* @throws \Throwable when the promise is rejected with a `Throwable` (PHP 7+)
* @throws \Throwable when the promise is rejected with a `Throwable`
* @throws \UnexpectedValueException when the promise is rejected with an unexpected value (Promise API v1 or v2 only)
*/
function await(PromiseInterface $promise)
Expand Down Expand Up @@ -79,7 +79,7 @@ function ($error) use (&$exception, &$rejected, &$wait) {

if ($rejected) {
// promise is rejected with an unexpected value (Promise API v1 or v2 only)
if (!$exception instanceof \Exception && !$exception instanceof \Throwable) {
if (!$exception instanceof \Throwable) {
$exception = new \UnexpectedValueException(
'Promise rejected with unexpected value of type ' . (is_object($exception) ? get_class($exception) : gettype($exception))
);
Expand All @@ -95,18 +95,18 @@ function ($error) use (&$exception, &$rejected, &$wait) {
* @param array<callable():PromiseInterface<mixed,Exception>> $tasks
* @return PromiseInterface<array<mixed>,Exception>
*/
function parallel(array $tasks)
function parallel(array $tasks): PromiseInterface
{
$pending = array();
$pending = [];
$deferred = new Deferred(function () use (&$pending) {
foreach ($pending as $promise) {
if ($promise instanceof CancellablePromiseInterface) {
$promise->cancel();
}
}
$pending = array();
$pending = [];
});
$results = array();
$results = [];
$errored = false;

$numTasks = count($tasks);
Expand All @@ -123,7 +123,7 @@ function parallel(array $tasks)
$promise->cancel();
}
}
$pending = array();
$pending = [];
};

foreach ($tasks as $i => $task) {
Expand Down Expand Up @@ -153,7 +153,7 @@ function parallel(array $tasks)
* @param array<callable():PromiseInterface<mixed,Exception>> $tasks
* @return PromiseInterface<array<mixed>,Exception>
*/
function series(array $tasks)
function series(array $tasks): PromiseInterface
{
$pending = null;
$deferred = new Deferred(function () use (&$pending) {
Expand All @@ -162,7 +162,7 @@ function series(array $tasks)
}
$pending = null;
});
$results = array();
$results = [];

/** @var callable():void $next */
$taskCallback = function ($result) use (&$results, &$next) {
Expand Down Expand Up @@ -193,7 +193,7 @@ function series(array $tasks)
* @param array<callable(mixed=):PromiseInterface<mixed,Exception>> $tasks
* @return PromiseInterface<mixed,Exception>
*/
function waterfall(array $tasks)
function waterfall(array $tasks): PromiseInterface
{
$pending = null;
$deferred = new Deferred(function () use (&$pending) {
Expand Down
41 changes: 13 additions & 28 deletions tests/AwaitTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,8 @@ public function testAwaitThrowsExceptionWhenPromiseIsRejectedWithException()
throw new \Exception('test');
});

$this->setExpectedException('Exception', 'test');
$this->expectException(\Exception::class);
$this->expectExceptionMessage('test');
React\Async\await($promise);
}

Expand All @@ -28,7 +29,8 @@ public function testAwaitThrowsUnexpectedValueExceptionWhenPromiseIsRejectedWith
$reject(false);
});

$this->setExpectedException('UnexpectedValueException', 'Promise rejected with unexpected value of type bool');
$this->expectException(\UnexpectedValueException::class);
$this->expectExceptionMessage('Promise rejected with unexpected value of type bool');
React\Async\await($promise);
}

Expand All @@ -42,20 +44,20 @@ public function testAwaitThrowsUnexpectedValueExceptionWhenPromiseIsRejectedWith
$reject(null);
});

$this->setExpectedException('UnexpectedValueException', 'Promise rejected with unexpected value of type NULL');
$this->expectException(\UnexpectedValueException::class);
$this->expectExceptionMessage('Promise rejected with unexpected value of type NULL');
React\Async\await($promise);
}

/**
* @requires PHP 7
*/
public function testAwaitThrowsErrorWhenPromiseIsRejectedWithError()
{
$promise = new Promise(function ($_, $reject) {
throw new \Error('Test', 42);
});

$this->setExpectedException('Error', 'Test', 42);
$this->expectException(\Error::class);
$this->expectExceptionMessage('Test');
$this->expectExceptionCode(42);
React\Async\await($promise);
}

Expand Down Expand Up @@ -84,8 +86,8 @@ public function testAwaitReturnsValueWhenPromiseIsFulfilledEvenWhenOtherTimerSto

public function testAwaitShouldNotCreateAnyGarbageReferencesForResolvedPromise()
{
if (class_exists('React\Promise\When') && PHP_VERSION_ID >= 50400) {
$this->markTestSkipped('Not supported on legacy Promise v1 API with PHP 5.4+');
if (class_exists('React\Promise\When')) {
$this->markTestSkipped('Not supported on legacy Promise v1 API');
}

gc_collect_cycles();
Expand Down Expand Up @@ -126,8 +128,8 @@ public function testAwaitShouldNotCreateAnyGarbageReferencesForPromiseRejectedWi
$this->markTestSkipped('Promises must be rejected with a \Throwable instance since Promise v3');
}

if (class_exists('React\Promise\When') && PHP_VERSION_ID >= 50400) {
$this->markTestSkipped('Not supported on legacy Promise v1 API with PHP 5.4+');
if (class_exists('React\Promise\When')) {
$this->markTestSkipped('Not supported on legacy Promise v1 API');
}

gc_collect_cycles();
Expand All @@ -144,21 +146,4 @@ public function testAwaitShouldNotCreateAnyGarbageReferencesForPromiseRejectedWi

$this->assertEquals(0, gc_collect_cycles());
}

public function setExpectedException($exception, $exceptionMessage = '', $exceptionCode = null)
{
if (method_exists($this, 'expectException')) {
// PHPUnit 5+
$this->expectException($exception);
if ($exceptionMessage !== '') {
$this->expectExceptionMessage($exceptionMessage);
}
if ($exceptionCode !== null) {
$this->expectExceptionCode($exceptionCode);
}
} else {
// legacy PHPUnit 4
parent::setExpectedException($exception, $exceptionMessage, $exceptionCode);
}
}
}
9 changes: 5 additions & 4 deletions tests/TestCase.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

namespace React\Tests\Async;

use PHPUnit\Framework\MockObject\MockBuilder;
use PHPUnit\Framework\TestCase as BaseTestCase;

class TestCase extends BaseTestCase
Expand Down Expand Up @@ -39,12 +40,12 @@ protected function expectCallableNever()

protected function createCallableMock()
{
if (method_exists('PHPUnit\Framework\MockObject\MockBuilder', 'addMethods')) {
if (method_exists(MockBuilder::class, 'addMethods')) {
// PHPUnit 9+
return $this->getMockBuilder('stdClass')->addMethods(array('__invoke'))->getMock();
return $this->getMockBuilder(\stdClass::class)->addMethods(['__invoke'])->getMock();
} else {
// legacy PHPUnit 4 - PHPUnit 8
return $this->getMockBuilder('stdClass')->setMethods(array('__invoke'))->getMock();
// PHPUnit < 9
return $this->getMockBuilder(\stdClass::class)->setMethods(['__invoke'])->getMock();
}
}
}