From cb78c99b69708b178d78434736598c68412189b8 Mon Sep 17 00:00:00 2001 From: Tobias Nyholm Date: Sat, 19 Sep 2020 11:49:50 +0200 Subject: [PATCH] Added CI with Github actions (#119) * Added CI with Github actions * Conservative CS fixes * Fix * Use Symfony PHPUnit bridge --- .github/workflows/.editorconfig | 2 + .github/workflows/ci.yml | 49 ++++++++++++++++++ .github/workflows/static.yml | 44 +++++++++++++++++ .gitignore | 3 ++ .php_cs.dist | 88 +++++++++++++++++++++++++++++++++ composer.json | 6 +-- phpstan-baseline.neon | 82 ++++++++++++++++++++++++++++++ phpstan.neon.dist | 7 +++ psalm.baseline.xml | 17 +++++++ psalm.xml | 16 ++++++ src/Coroutine.php | 1 + src/EachPromise.php | 14 ++++-- src/FulfilledPromise.php | 3 +- src/Is.php | 8 --- src/RejectedPromise.php | 3 +- src/RejectionException.php | 2 +- src/TaskQueueInterface.php | 2 - src/Utils.php | 2 +- src/functions.php | 9 ---- tests/CoroutineTest.php | 2 +- tests/EachPromiseTest.php | 5 +- tests/FulfilledPromiseTest.php | 13 ++--- tests/NotPromiseInstance.php | 2 - tests/PromiseTest.php | 69 +++++++++++--------------- tests/RejectedPromiseTest.php | 11 +++-- tests/UtilsTest.php | 39 +++++++-------- 26 files changed, 393 insertions(+), 106 deletions(-) create mode 100644 .github/workflows/.editorconfig create mode 100644 .github/workflows/ci.yml create mode 100644 .github/workflows/static.yml create mode 100644 .php_cs.dist create mode 100644 phpstan-baseline.neon create mode 100644 phpstan.neon.dist create mode 100644 psalm.baseline.xml create mode 100644 psalm.xml diff --git a/.github/workflows/.editorconfig b/.github/workflows/.editorconfig new file mode 100644 index 0000000..7bd3346 --- /dev/null +++ b/.github/workflows/.editorconfig @@ -0,0 +1,2 @@ +[*.yml] +indent_size = 2 diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 0000000..14dc509 --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,49 @@ +name: Tests +on: [push, pull_request] + +jobs: + build: + name: Build + runs-on: ubuntu-latest + strategy: + max-parallel: 10 + matrix: + php: [ '5.5', '5.6', '7.0', '7.1', '7.2', '7.3', '7.4'] + + steps: + - name: Set up PHP + uses: shivammathur/setup-php@2.5.0 + with: + php-version: ${{ matrix.php }} + coverage: none + tools: flex + + - name: Checkout code + uses: actions/checkout@v2 + + - name: Download dependencies + run: composer update --no-interaction --prefer-dist --optimize-autoloader --prefer-stable + + - name: Run tests + run: ./vendor/bin/phpunit + + lowest: + name: Lowest deps + runs-on: ubuntu-latest + steps: + - name: Set up PHP + uses: shivammathur/setup-php@2.5.0 + with: + php-version: 7.3 + coverage: pcov + + - name: Checkout code + uses: actions/checkout@v2 + + - name: Download dependencies + run: composer update --no-interaction --prefer-dist --optimize-autoloader --prefer-stable --prefer-lowest + + - name: Run tests + env: + SYMFONY_DEPRECATIONS_HELPER: "max[self]=0" + run: ./vendor/bin/phpunit --coverage-text diff --git a/.github/workflows/static.yml b/.github/workflows/static.yml new file mode 100644 index 0000000..27f3d74 --- /dev/null +++ b/.github/workflows/static.yml @@ -0,0 +1,44 @@ +on: [push, pull_request] +name: Static analysis + +jobs: + phpstan: + name: PHPStan + runs-on: ubuntu-latest + + steps: + - name: Checkout code + uses: actions/checkout@v2 + + - name: Download dependencies + run: | + composer update --no-interaction --prefer-dist --optimize-autoloader + + - name: PHPStan + uses: docker://oskarstark/phpstan-ga:0.12.23 + with: + entrypoint: /composer/vendor/bin/phpstan + args: analyze --no-progress + + php-cs-fixer: + name: PHP-CS-Fixer + runs-on: ubuntu-latest + + steps: + - name: Checkout code + uses: actions/checkout@v2 + + - name: PHP-CS-Fixer + uses: OskarStark/php-cs-fixer-ga@2.16.3.1 + with: + args: --dry-run --diff-format udiff + + psalm: + name: Psalm + runs-on: ubuntu-latest + steps: + - name: Checkout code + uses: actions/checkout@v2 + + - name: Psalm + uses: docker://vimeo/psalm-github-actions diff --git a/.gitignore b/.gitignore index 84c37d9..2383510 100644 --- a/.gitignore +++ b/.gitignore @@ -2,3 +2,6 @@ artifacts/ vendor/ composer.lock phpunit.xml +.php_cs +.php_cs.cache +.phpunit.result.cache diff --git a/.php_cs.dist b/.php_cs.dist new file mode 100644 index 0000000..a321876 --- /dev/null +++ b/.php_cs.dist @@ -0,0 +1,88 @@ +setRiskyAllowed(true) + ->setRules([ + '@PSR2' => true, + 'array_syntax' => ['syntax' => 'short'], + 'binary_operator_spaces' => ['operators' => ['=>' => null]], + 'blank_line_after_opening_tag' => true, + 'class_attributes_separation' => ['elements' => ['method']], + 'compact_nullable_typehint' => true, + 'concat_space' => ['spacing' => 'one'], + 'declare_equal_normalize' => ['space' => 'none'], + 'declare_strict_types' => false, + 'dir_constant' => true, + 'final_static_access' => true, + 'fully_qualified_strict_types' => true, + 'function_to_constant' => true, + 'function_typehint_space' => true, + 'header_comment' => false, + 'is_null' => ['use_yoda_style' => false], + 'list_syntax' => ['syntax' => 'short'], + 'lowercase_cast' => true, + 'magic_method_casing' => true, + 'modernize_types_casting' => true, + 'multiline_comment_opening_closing' => true, + //'native_constant_invocation' => true, + 'no_alias_functions' => true, + 'no_alternative_syntax' => true, + 'no_blank_lines_after_phpdoc' => true, + 'no_empty_comment' => true, + 'no_empty_phpdoc' => true, + 'no_extra_blank_lines' => true, + 'no_leading_import_slash' => true, + 'no_leading_namespace_whitespace' => true, + 'no_spaces_around_offset' => true, + 'no_superfluous_phpdoc_tags' => ['allow_mixed' => true], + 'no_trailing_comma_in_singleline_array' => true, + 'no_unneeded_control_parentheses' => true, + 'no_unset_cast' => true, + 'no_unused_imports' => true, + 'no_useless_else' => true, + 'no_useless_return' => true, + 'no_whitespace_in_blank_line' => true, + 'normalize_index_brace' => true, + 'ordered_imports' => true, + 'php_unit_construct' => true, + 'php_unit_dedicate_assert' => ['target' => 'newest'], + 'php_unit_dedicate_assert_internal_type' => ['target' => 'newest'], + 'php_unit_expectation' => ['target' => 'newest'], + 'php_unit_mock' => ['target' => 'newest'], + 'php_unit_mock_short_will_return' => true, + 'php_unit_no_expectation_annotation' => ['target' => 'newest'], + 'php_unit_test_annotation' => ['style' => 'prefix'], + //'php_unit_test_case_static_method_calls' => ['call_type' => 'self'], + 'phpdoc_align' => ['align' => 'vertical'], + //'phpdoc_line_span' => ['method' => 'multi', 'property' => 'multi'], + 'phpdoc_no_package' => true, + 'phpdoc_no_useless_inheritdoc' => true, + 'phpdoc_scalar' => true, + 'phpdoc_separation' => true, + 'phpdoc_single_line_var_spacing' => true, + 'phpdoc_trim' => true, + 'phpdoc_trim_consecutive_blank_line_separation' => true, + 'phpdoc_types' => true, + 'phpdoc_types_order' => ['null_adjustment' => 'always_last', 'sort_algorithm' => 'none'], + 'phpdoc_var_without_name' => true, + 'return_assignment' => true, + 'short_scalar_cast' => true, + 'single_trait_insert_per_statement' => true, + 'standardize_not_equals' => true, + //'static_lambda' => true, + 'ternary_to_null_coalescing' => true, + 'trim_array_spaces' => true, + 'visibility_required' => true, + 'yoda_style' => false, + // 'native_function_invocation' => true, + 'braces' => ['allow_single_line_closure'=>true], + ]) + ->setFinder( + PhpCsFixer\Finder::create() + ->in(__DIR__.'/src') + ->in(__DIR__.'/tests') + ->name('*.php') + ) +; + +return $config; diff --git a/composer.json b/composer.json index e968e68..db44d9e 100644 --- a/composer.json +++ b/composer.json @@ -14,7 +14,7 @@ "php": ">=5.5" }, "require-dev": { - "phpunit/phpunit": "^4.8.36 || ^5.7.27 || ^7.5" + "symfony/phpunit-bridge": "^4.4 || ^5.1" }, "autoload": { "psr-4": { @@ -28,8 +28,8 @@ } }, "scripts": { - "test": "vendor/bin/phpunit", - "test-ci": "vendor/bin/phpunit --coverage-text" + "test": "vendor/bin/simple-phpunit", + "test-ci": "vendor/bin/simple-phpunit --coverage-text" }, "extra": { "branch-alias": { diff --git a/phpstan-baseline.neon b/phpstan-baseline.neon new file mode 100644 index 0000000..08be229 --- /dev/null +++ b/phpstan-baseline.neon @@ -0,0 +1,82 @@ +parameters: + ignoreErrors: + - + message: "#^If condition is always true\\.$#" + count: 3 + path: src/EachPromise.php + + - + message: "#^Unreachable statement \\- code above always terminates\\.$#" + count: 1 + path: src/EachPromise.php + + - + message: "#^Property GuzzleHttp\\\\Promise\\\\EachPromise\\:\\:\\$concurrency \\(\\(callable\\(\\)\\: mixed\\)\\|int\\) does not accept null\\.$#" + count: 1 + path: src/EachPromise.php + + - + message: "#^Property GuzzleHttp\\\\Promise\\\\EachPromise\\:\\:\\$iterable \\(Iterator\\) does not accept null\\.$#" + count: 1 + path: src/EachPromise.php + + - + message: "#^Property GuzzleHttp\\\\Promise\\\\EachPromise\\:\\:\\$onFulfilled \\(callable\\(\\)\\: mixed\\) does not accept null\\.$#" + count: 1 + path: src/EachPromise.php + + - + message: "#^Property GuzzleHttp\\\\Promise\\\\EachPromise\\:\\:\\$onRejected \\(callable\\(\\)\\: mixed\\) does not accept null\\.$#" + count: 1 + path: src/EachPromise.php + + - + message: "#^Negated boolean expression is always false\\.$#" + count: 1 + path: src/EachPromise.php + + - + message: "#^Dead catch \\- Exception is already caught by Throwable above\\.$#" + count: 1 + path: src/EachPromise.php + + - + message: "#^Dead catch \\- Exception is already caught by Throwable above\\.$#" + count: 1 + path: src/FulfilledPromise.php + + - + message: "#^Dead catch \\- Exception is already caught by Throwable above\\.$#" + count: 2 + path: src/Promise.php + + - + message: "#^Method GuzzleHttp\\\\Promise\\\\Promise\\:\\:callHandler\\(\\) should return array but empty return statement found\\.$#" + count: 1 + path: src/Promise.php + + - + message: "#^Method GuzzleHttp\\\\Promise\\\\Promise\\:\\:callHandler\\(\\) should return array but return statement is missing\\.$#" + count: 1 + path: src/Promise.php + + - + message: "#^Dead catch \\- Exception is already caught by Throwable above\\.$#" + count: 1 + path: src/RejectedPromise.php + + - + message: "#^Parameter \\#1 \\$function of function register_shutdown_function expects callable\\(\\)\\: void, Closure\\(\\)\\: mixed given\\.$#" + count: 1 + path: src/TaskQueue.php + + - + message: "#^Variable \\$task in PHPDoc tag @var does not exist\\.$#" + count: 1 + path: src/TaskQueue.php + + - + message: "#^Dead catch \\- Exception is already caught by Throwable above\\.$#" + count: 2 + path: src/Utils.php + diff --git a/phpstan.neon.dist b/phpstan.neon.dist new file mode 100644 index 0000000..bc0f2c3 --- /dev/null +++ b/phpstan.neon.dist @@ -0,0 +1,7 @@ +includes: + - phpstan-baseline.neon + +parameters: + level: 5 + paths: + - src diff --git a/psalm.baseline.xml b/psalm.baseline.xml new file mode 100644 index 0000000..0e5dc82 --- /dev/null +++ b/psalm.baseline.xml @@ -0,0 +1,17 @@ + + + + + array + + + $this->state === self::PENDING + $this->state === self::PENDING + + + + + wait + + + diff --git a/psalm.xml b/psalm.xml new file mode 100644 index 0000000..e044bd6 --- /dev/null +++ b/psalm.xml @@ -0,0 +1,16 @@ + + + + + + + + + diff --git a/src/Coroutine.php b/src/Coroutine.php index c29cfd2..670da47 100644 --- a/src/Coroutine.php +++ b/src/Coroutine.php @@ -39,6 +39,7 @@ * @param callable $generatorFn Generator function to wrap into a promise. * * @return Promise + * * @link https://github.com/petkaantonov/bluebird/blob/master/API.md#generators inspiration */ final class Coroutine implements PromiseInterface diff --git a/src/EachPromise.php b/src/EachPromise.php index 04ca9cc..d641f68 100644 --- a/src/EachPromise.php +++ b/src/EachPromise.php @@ -46,8 +46,8 @@ class EachPromise implements PromisorInterface * allowed number of outstanding concurrently executing promises, * creating a capped pool of promises. There is no limit by default. * - * @param mixed $iterable Promises or values to iterate. - * @param array $config Configuration options + * @param mixed $iterable Promises or values to iterate. + * @param array $config Configuration options */ public function __construct($iterable, array $config = []) { @@ -159,7 +159,10 @@ private function addPending() function ($value) use ($idx, $key) { if ($this->onFulfilled) { call_user_func( - $this->onFulfilled, $value, $key, $this->aggregate + $this->onFulfilled, + $value, + $key, + $this->aggregate ); } $this->step($idx); @@ -167,7 +170,10 @@ function ($value) use ($idx, $key) { function ($reason) use ($idx, $key) { if ($this->onRejected) { call_user_func( - $this->onRejected, $reason, $key, $this->aggregate + $this->onRejected, + $reason, + $key, + $this->aggregate ); } $this->step($idx); diff --git a/src/FulfilledPromise.php b/src/FulfilledPromise.php index 0f02e67..98f72a6 100644 --- a/src/FulfilledPromise.php +++ b/src/FulfilledPromise.php @@ -16,7 +16,8 @@ public function __construct($value) { if (is_object($value) && method_exists($value, 'then')) { throw new \InvalidArgumentException( - 'You cannot create a FulfilledPromise with a promise.'); + 'You cannot create a FulfilledPromise with a promise.' + ); } $this->value = $value; diff --git a/src/Is.php b/src/Is.php index 80ba4f1..c3ed8d0 100644 --- a/src/Is.php +++ b/src/Is.php @@ -7,8 +7,6 @@ final class Is /** * Returns true if a promise is pending. * - * @param PromiseInterface $promise - * * @return bool */ public static function pending(PromiseInterface $promise) @@ -19,8 +17,6 @@ public static function pending(PromiseInterface $promise) /** * Returns true if a promise is fulfilled or rejected. * - * @param PromiseInterface $promise - * * @return bool */ public static function settled(PromiseInterface $promise) @@ -31,8 +27,6 @@ public static function settled(PromiseInterface $promise) /** * Returns true if a promise is fulfilled. * - * @param PromiseInterface $promise - * * @return bool */ public static function fulfilled(PromiseInterface $promise) @@ -43,8 +37,6 @@ public static function fulfilled(PromiseInterface $promise) /** * Returns true if a promise is rejected. * - * @param PromiseInterface $promise - * * @return bool */ public static function rejected(PromiseInterface $promise) diff --git a/src/RejectedPromise.php b/src/RejectedPromise.php index 3f5f838..fd8c633 100644 --- a/src/RejectedPromise.php +++ b/src/RejectedPromise.php @@ -16,7 +16,8 @@ public function __construct($reason) { if (is_object($reason) && method_exists($reason, 'then')) { throw new \InvalidArgumentException( - 'You cannot create a RejectedPromise with a promise.'); + 'You cannot create a RejectedPromise with a promise.' + ); } $this->reason = $reason; diff --git a/src/RejectionException.php b/src/RejectionException.php index 8fbadc4..e2f1377 100644 --- a/src/RejectionException.php +++ b/src/RejectionException.php @@ -13,7 +13,7 @@ class RejectionException extends \RuntimeException private $reason; /** - * @param mixed $reason Rejection reason. + * @param mixed $reason Rejection reason. * @param string $description Optional description */ public function __construct($reason, $description = null) diff --git a/src/TaskQueueInterface.php b/src/TaskQueueInterface.php index 6e845b0..723d4d5 100644 --- a/src/TaskQueueInterface.php +++ b/src/TaskQueueInterface.php @@ -14,8 +14,6 @@ public function isEmpty(); /** * Adds a task to the queue that will be executed the next time run is * called. - * - * @param callable $task */ public function add(callable $task); diff --git a/src/Utils.php b/src/Utils.php index 036ca06..1cee862 100644 --- a/src/Utils.php +++ b/src/Utils.php @@ -166,7 +166,7 @@ function ($reason, $idx, Promise $aggregate) { if (true === $recursive) { $promise = $promise->then(function ($results) use ($recursive, &$promises) { - foreach ($promises AS $promise) { + foreach ($promises as $promise) { if (Is::pending($promise)) { return self::all($promises, $recursive); } diff --git a/src/functions.php b/src/functions.php index 451995b..4fd9d03 100644 --- a/src/functions.php +++ b/src/functions.php @@ -299,7 +299,6 @@ function each_limit( * @param mixed $iterable * @param int|callable $concurrency * @param callable $onFulfilled - * * @param mixed $iterable * @param int|callable $concurrency * @param callable $onFulfilled @@ -319,8 +318,6 @@ function each_limit_all( /** * Returns true if a promise is fulfilled. * - * @param PromiseInterface $promise - * * @return bool * * @deprecated is_fulfilled will be removed in guzzlehttp/promises:2.0. Use Is::fulfilled instead. @@ -333,8 +330,6 @@ function is_fulfilled(PromiseInterface $promise) /** * Returns true if a promise is rejected. * - * @param PromiseInterface $promise - * * @return bool * * @deprecated is_rejected will be removed in guzzlehttp/promises:2.0. Use Is::rejected instead. @@ -347,8 +342,6 @@ function is_rejected(PromiseInterface $promise) /** * Returns true if a promise is fulfilled or rejected. * - * @param PromiseInterface $promise - * * @return bool * * @deprecated is_settled will be removed in guzzlehttp/promises:2.0. Use Is::settled instead. @@ -363,8 +356,6 @@ function is_settled(PromiseInterface $promise) * * @see Coroutine * - * @param callable $generatorFn - * * @return PromiseInterface * * @deprecated coroutine will be removed in guzzlehttp/promises:2.0. Use Coroutine::of instead. diff --git a/tests/CoroutineTest.php b/tests/CoroutineTest.php index 6b2c3fa..ed91a8c 100644 --- a/tests/CoroutineTest.php +++ b/tests/CoroutineTest.php @@ -21,7 +21,7 @@ public function testReturnsCoroutine() * @dataProvider promiseInterfaceMethodProvider * * @param string $method - * @param array $args + * @param array $args */ public function testShouldProxyPromiseMethodsToResultPromise($method, $args = []) { diff --git a/tests/EachPromiseTest.php b/tests/EachPromiseTest.php index d4c92a7..8c58d85 100644 --- a/tests/EachPromiseTest.php +++ b/tests/EachPromiseTest.php @@ -3,10 +3,10 @@ namespace GuzzleHttp\Promise\Tests; use GuzzleHttp\Promise as P; -use GuzzleHttp\Promise\RejectedPromise; +use GuzzleHttp\Promise\EachPromise; use GuzzleHttp\Promise\FulfilledPromise; use GuzzleHttp\Promise\Promise; -use GuzzleHttp\Promise\EachPromise; +use GuzzleHttp\Promise\RejectedPromise; use PHPUnit\Framework\TestCase; /** @@ -317,6 +317,7 @@ private function createSelfResolvingPromise($value) $p = new Promise(function () use (&$p, $value) { $p->resolve($value); }); + $trickCsFixer = true; return $p; } diff --git a/tests/FulfilledPromiseTest.php b/tests/FulfilledPromiseTest.php index 54752e1..2459311 100644 --- a/tests/FulfilledPromiseTest.php +++ b/tests/FulfilledPromiseTest.php @@ -3,8 +3,8 @@ namespace GuzzleHttp\Tests\Promise; use GuzzleHttp\Promise as P; -use GuzzleHttp\Promise\Promise; use GuzzleHttp\Promise\FulfilledPromise; +use GuzzleHttp\Promise\Promise; use PHPUnit\Framework\TestCase; /** @@ -28,21 +28,23 @@ public function testCannotCancel() } /** - * @expectedException \LogicException * @exepctedExceptionMessage Cannot resolve a fulfilled promise */ public function testCannotResolve() { + $this->expectException(\LogicException::class); + $p = new FulfilledPromise('foo'); $p->resolve('bar'); } /** - * @expectedException \LogicException * @exepctedExceptionMessage Cannot reject a fulfilled promise */ public function testCannotReject() { + $this->expectException(\LogicException::class); + $p = new FulfilledPromise('foo'); $p->reject('bar'); } @@ -54,11 +56,10 @@ public function testCanResolveWithSameValue() $this->assertSame('foo', $p->wait()); } - /** - * @expectedException \InvalidArgumentException - */ public function testCannotResolveWithPromise() { + $this->expectException(\InvalidArgumentException::class); + new FulfilledPromise(new Promise()); } diff --git a/tests/NotPromiseInstance.php b/tests/NotPromiseInstance.php index c137185..bb1bc76 100644 --- a/tests/NotPromiseInstance.php +++ b/tests/NotPromiseInstance.php @@ -36,12 +36,10 @@ public function reject($reason) public function wait($unwrap = true, $defaultResolution = null) { - } public function cancel() { - } public function getState() diff --git a/tests/PromiseTest.php b/tests/PromiseTest.php index 6936e9b..ef15ca3 100644 --- a/tests/PromiseTest.php +++ b/tests/PromiseTest.php @@ -15,12 +15,11 @@ */ class PromiseTest extends TestCase { - /** - * @expectedException \LogicException - * @expectedExceptionMessage The promise is already fulfilled - */ public function testCannotResolveNonPendingPromise() { + $this->expectException(\LogicException::class); + $this->expectExceptionMessage('The promise is already fulfilled'); + $p = new Promise(); $p->resolve('foo'); $p->resolve('bar'); @@ -35,12 +34,11 @@ public function testCanResolveWithSameValue() $this->assertSame('foo', $p->wait()); } - /** - * @expectedException \LogicException - * @expectedExceptionMessage Cannot change a fulfilled promise to rejected - */ public function testCannotRejectNonPendingPromise() { + $this->expectException(\LogicException::class); + $this->expectExceptionMessage('Cannot change a fulfilled promise to rejected'); + $p = new Promise(); $p->resolve('foo'); $p->reject('bar'); @@ -55,12 +53,11 @@ public function testCanRejectWithSameValue() $this->assertTrue(P\Is::rejected($p)); } - /** - * @expectedException \LogicException - * @expectedExceptionMessage Cannot change a fulfilled promise to rejected - */ public function testCannotRejectResolveWithSameValue() { + $this->expectException(\LogicException::class); + $this->expectExceptionMessage('Cannot change a fulfilled promise to rejected'); + $p = new Promise(); $p->resolve('foo'); $p->reject('foo'); @@ -72,32 +69,29 @@ public function testInvokesWaitFunction() $this->assertSame('10', $p->wait()); } - /** - * @expectedException \GuzzleHttp\Promise\RejectionException - * @expectedExceptionMessage The promise was rejected with reason: Invoking the wait callback did not resolve the promise - */ public function testRejectsAndThrowsWhenWaitFailsToResolve() { + $this->expectException(\GuzzleHttp\Promise\RejectionException::class); + $this->expectExceptionMessage('The promise was rejected with reason: Invoking the wait callback did not resolve the promise'); + $p = new Promise(function () {}); $p->wait(); } - /** - * @expectedException \GuzzleHttp\Promise\RejectionException - * @expectedExceptionMessage The promise was rejected with reason: foo - */ public function testThrowsWhenUnwrapIsRejectedWithNonException() { + $this->expectException(\GuzzleHttp\Promise\RejectionException::class); + $this->expectExceptionMessage('The promise was rejected with reason: foo'); + $p = new Promise(function () use (&$p) { $p->reject('foo'); }); $p->wait(); } - /** - * @expectedException \UnexpectedValueException - * @expectedExceptionMessage foo - */ public function testThrowsWhenUnwrapIsRejectedWithException() { + $this->expectException(\UnexpectedValueException::class); + $this->expectExceptionMessage('foo'); + $e = new \UnexpectedValueException('foo'); $p = new Promise(function () use (&$p, $e) { $p->reject($e); }); $p->wait(); @@ -131,11 +125,10 @@ public function testWaitsOnNestedPromises() $this->assertSame('foo', $p3->wait()); } - /** - * @expectedException \GuzzleHttp\Promise\RejectionException - */ public function testThrowsWhenWaitingOnPromiseWithNoWaitFunction() { + $this->expectException(\GuzzleHttp\Promise\RejectionException::class); + $p = new Promise(); $p->wait(); } @@ -198,11 +191,10 @@ public function testCannotCancelNonPending() $this->assertTrue(P\Is::fulfilled($p)); } - /** - * @expectedException \GuzzleHttp\Promise\CancellationException - */ public function testCancelsPromiseWhenNoCancelFunction() { + $this->expectException(\GuzzleHttp\Promise\CancellationException::class); + $p = new Promise(); $p->cancel(); $this->assertTrue(P\Is::rejected($p)); @@ -465,7 +457,8 @@ public function testRemovesReferenceFromChildWhenParentWaitedUpon() function ($v) use ($p2, &$r) { $r = $v; return $p2; - }) + } + ) ->then(function ($v) { return $v . '.'; }); $this->assertSame('a', $p->wait()); $this->assertSame('b', $p2->wait()); @@ -552,22 +545,20 @@ public function testRecursivelyForwardsWhenNotInstanceOfPromise() $this->assertSame(['B', 'D:a', 'A:foo', 'C:foo'], $res); } - /** - * @expectedException \LogicException - * @expectedExceptionMessage Cannot fulfill or reject a promise with itself - */ public function testCannotResolveWithSelf() { + $this->expectException(\LogicException::class); + $this->expectExceptionMessage('Cannot fulfill or reject a promise with itself'); + $p = new Promise(); $p->resolve($p); } - /** - * @expectedException \LogicException - * @expectedExceptionMessage Cannot fulfill or reject a promise with itself - */ public function testCannotRejectWithSelf() { + $this->expectException(\LogicException::class); + $this->expectExceptionMessage('Cannot fulfill or reject a promise with itself'); + $p = new Promise(); $p->reject($p); } diff --git a/tests/RejectedPromiseTest.php b/tests/RejectedPromiseTest.php index dd74cc0..9b167e7 100644 --- a/tests/RejectedPromiseTest.php +++ b/tests/RejectedPromiseTest.php @@ -33,21 +33,23 @@ public function testCannotCancel() } /** - * @expectedException \LogicException * @exepctedExceptionMessage Cannot resolve a rejected promise */ public function testCannotResolve() { + $this->expectException(\LogicException::class); + $p = new RejectedPromise('foo'); $p->resolve('bar'); } /** - * @expectedException \LogicException * @exepctedExceptionMessage Cannot reject a rejected promise */ public function testCannotReject() { + $this->expectException(\LogicException::class); + $p = new RejectedPromise('foo'); $p->reject('bar'); } @@ -71,11 +73,10 @@ public function testThrowsSpecificException() } } - /** - * @expectedException \InvalidArgumentException - */ public function testCannotResolveWithPromise() { + $this->expectException(\InvalidArgumentException::class); + new RejectedPromise(new Promise()); } diff --git a/tests/UtilsTest.php b/tests/UtilsTest.php index f956104..2974a28 100644 --- a/tests/UtilsTest.php +++ b/tests/UtilsTest.php @@ -2,8 +2,8 @@ namespace GuzzleHttp\Promise\Tests; -use GuzzleHttp\Promise as P; use GuzzleHttp\Promise\AggregateException; +use GuzzleHttp\Promise as P; use GuzzleHttp\Promise\FulfilledPromise; use GuzzleHttp\Promise\Promise; use GuzzleHttp\Promise\PromiseInterface; @@ -28,11 +28,10 @@ public function testWaitsOnAllPromisesIntoArray() ], $results); } - /** - * @expectedException \GuzzleHttp\Promise\RejectionException - */ public function testUnwrapsPromisesWithNoDefaultAndFailure() { + $this->expectException(\GuzzleHttp\Promise\RejectionException::class); + $promises = [new FulfilledPromise('a'), new Promise()]; P\Utils::unwrap($promises); } @@ -148,23 +147,21 @@ public function testCanWaitUntilSomeCountIsSatisfied() $this->assertSame(['a', 'b'], $d->wait()); } - /** - * @expectedException \GuzzleHttp\Promise\AggregateException - * @expectedExceptionMessage Not enough promises to fulfill count - */ public function testThrowsIfImpossibleToWaitForSomeCount() { + $this->expectException(\GuzzleHttp\Promise\AggregateException::class); + $this->expectExceptionMessage('Not enough promises to fulfill count'); + $a = new Promise(function () use (&$a) { $a->resolve('a'); }); $d = P\Utils::some(2, [$a]); $d->wait(); } - /** - * @expectedException \GuzzleHttp\Promise\AggregateException - * @expectedExceptionMessage Not enough promises to fulfill count - */ public function testThrowsIfResolvedWithoutCountTotalResults() { + $this->expectException(\GuzzleHttp\Promise\AggregateException::class); + $this->expectExceptionMessage('Not enough promises to fulfill count'); + $a = new Promise(); $b = new Promise(); $d = P\Utils::some(3, [$a, $b]); @@ -322,14 +319,14 @@ function ($reason) use (&$result) { $result = $reason; } public function rejectsParentExceptionProvider() { return [ - [ P\Coroutine::of(function () { + [P\Coroutine::of(function () { yield new FulfilledPromise(0); throw new \Exception('a'); - }) ], - [ P\Coroutine::of(function () { + })], + [P\Coroutine::of(function () { throw new \Exception('a'); yield new FulfilledPromise(0); - }) ], + })], ]; } @@ -534,7 +531,7 @@ public function testYieldFinalWaitablePromise() $p2 = new Promise(function () use (&$p2) { $p2->resolve('hello!'); }); - $co = P\Coroutine::of(function() use ($p1, $p2) { + $co = P\Coroutine::of(function () use ($p1, $p2) { yield $p1; yield $p2; }); @@ -550,7 +547,7 @@ public function testCanYieldFinalPendingPromise() $p1 = new Promise(); $p2 = new Promise(); - $co = P\Coroutine::of(function() use ($p1, $p2) { + $co = P\Coroutine::of(function () use ($p1, $p2) { yield $p1; yield $p2; }); @@ -572,7 +569,7 @@ public function testCanNestYieldsAndFailures() $p3 = new Promise(); $p4 = new Promise(); $p5 = new Promise(); - $co = P\Coroutine::of(function() use ($p1, $p2, $p3, $p4, $p5) { + $co = P\Coroutine::of(function () use ($p1, $p2, $p3, $p4, $p5) { try { yield $p1; } catch (\Exception $e) { @@ -606,7 +603,7 @@ public function testCanYieldErrorsAndSuccessesWithoutRecursion() $promises[] = new Promise(); } - $co = P\Coroutine::of(function() use ($promises) { + $co = P\Coroutine::of(function () use ($promises) { for ($i = 0; $i < 20; $i += 4) { try { yield $promises[$i]; @@ -672,7 +669,7 @@ public function testCanWaitOnErroredPromises() $p5 = new Promise(function () use (&$p5) { $p5->resolve('e'); }); $p6 = new Promise(function () use (&$p6) { $p6->reject('f'); }); - $co = P\Coroutine::of(function() use ($p1, $p2, $p3, $p4, $p5, $p6) { + $co = P\Coroutine::of(function () use ($p1, $p2, $p3, $p4, $p5, $p6) { try { yield $p1; } catch (\Exception $e) {