diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 0000000..691cd86 --- /dev/null +++ b/.editorconfig @@ -0,0 +1,19 @@ +root = true + +[*] +charset = utf-8 +end_of_line = lf +indent_size = 2 +indent_style = space +insert_final_newline = true +trim_trailing_whitespace = true + +[*.md] +indent_size = 4 +trim_trailing_whitespace = false + +[*.mk,Makefile] +indent_style = tab + +[*.php] +indent_size = 4 diff --git a/.gitignore b/.gitignore index 484fa0a..c9a1f98 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,5 @@ /vendor/ +/bin composer.lock composer.phar phpunit.xml diff --git a/.php_cs b/.php_cs index 938a00e..9230168 100644 --- a/.php_cs +++ b/.php_cs @@ -9,9 +9,6 @@ * file that was distributed with this source code. */ -require_once __DIR__.'/vendor/autoload.php'; - -use SLLH\StyleCIBridge\ConfigBridge; use Symfony\CS\Fixer\Contrib\HeaderCommentFixer; $header = <<setRules(array_merge($config->getRules(), [ - 'header_comment' => ['header' => $header] - ])); -} - -return $config - ->setUsingCache(true) - ->fixers(array_merge($config->getFixers(), ['header_comment'])) -; +return PhpCsFixer\Config::create() + ->setRules([ + '@PSR2' => true, + 'array_syntax' => ['syntax' => 'short'], + 'no_unreachable_default_argument_value' => false, + 'heredoc_to_nowdoc' => false, + 'header_comment' => ['header' => $header], + ]) + ->setRiskyAllowed(true) + ->setFinder( + PhpCsFixer\Finder::create() + ->in(__DIR__) + ->exclude(['vendor']) + ) + ; diff --git a/.styleci.yml b/.styleci.yml deleted file mode 100644 index 4571953..0000000 --- a/.styleci.yml +++ /dev/null @@ -1,7 +0,0 @@ -preset: psr2 -enabled: - - ordered_use - - short_array_syntax - -disabled: - - unalign_equals diff --git a/.travis.yml b/.travis.yml index 9a086e3..a03f560 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,33 +1,35 @@ language: php php: - - nightly - - hhvm - - 5.5 - - 5.6 - - 7.0 - - 7.1 + - 5.5 + - 5.6 + - 7.0 + - 7.1 + - nightly + - hhvm branches: - only: - - master - - /^\d+\.\d+$/ + only: + - master + - /^\d+\.\d+$/ -allow_failures: +matrix: + allow_failures: - php: nightly cache: - directories: - - $HOME/.composer/cache + directories: + - $HOME/.composer/cache before_install: - - if [[ "$TRAVIS_PHP_VERSION" != "5.6" && "$TRAVIS_PHP_VERSION" != "hhvm" ]]; then phpenv config-rm xdebug.ini || true; fi - - composer selfupdate - - composer require "guzzlehttp/promises" + - if [[ "$TRAVIS_PHP_VERSION" != "5.6" && "$TRAVIS_PHP_VERSION" != "hhvm" ]]; then phpenv config-rm xdebug.ini || true; fi + - composer selfupdate install: composer update --prefer-dist --no-interaction -script: if [ "$TRAVIS_PHP_VERSION" == "5.6" ]; then phpunit -d xdebug.max_nesting_level=1000 --debug --coverage-clover build/logs/clover.xml; else phpunit --debug; fi +script: + - if [ "$TRAVIS_PHP_VERSION" == "5.6" ]; then bin/phpunit --debug --coverage-clover build/logs/clover.xml; else bin/phpunit --debug; fi + - if [ "$TRAVIS_PHP_VERSION" == "7.0" ]; then composer require "friendsofphp/php-cs-fixer:^2.0" && bin/php-cs-fixer fix --diff --dry-run -v; fi; after_success: - - if [ "$TRAVIS_PHP_VERSION" == "5.6" ]; then composer require "satooshi/php-coveralls:^1.0" && travis_retry php vendor/bin/coveralls -v; fi + - if [ "$TRAVIS_PHP_VERSION" == "5.6" ]; then composer require "satooshi/php-coveralls:^1.0" && travis_retry php bin/coveralls -v; fi diff --git a/LICENSE.txt b/LICENSE similarity index 100% rename from LICENSE.txt rename to LICENSE diff --git a/README.md b/README.md index 86a4a9b..4682eb6 100644 --- a/README.md +++ b/README.md @@ -31,9 +31,9 @@ Create loaders by providing a batch loading instance. use Overblog\DataLoader\DataLoader; $myBatchGetUsers = function ($keys) { /* ... */ }; -$promiseFactory = new MyPromiseFactory(); +$promiseAdapter = new MyPromiseAdapter(); -$userLoader = new DataLoader($myBatchGetUsers, $promiseFactory); +$userLoader = new DataLoader($myBatchGetUsers, $promiseAdapter); ``` A batch loading callable / callback accepts an Array of keys, and returns a Promise which @@ -123,12 +123,12 @@ Each `DataLoaderPHP` instance contains a unique memoized cache. Use caution when used in long-lived applications or those which serve many users with different access permissions and consider creating a new instance per web request. -##### `new DataLoader(callable $batchLoadFn, PromiseFactoryInterface $promiseFactory [, Option $options])` +##### `new DataLoader(callable $batchLoadFn, PromiseAdapterInterface $promiseAdapter [, Option $options])` Create a new `DataLoaderPHP` given a batch loading instance and options. - *$batchLoadFn*: A callable / callback which accepts an Array of keys, and returns a Promise which resolves to an Array of values. -- *$promiseFactory*: Any object that implements `McGWeb\PromiseFactory\PromiseFactoryInterface`. (see [McGWeb/Promise-Factory](https://github.com/mcg-web/promise-factory)) +- *$promiseAdapter*: Any object that implements `Overblog\PromiseAdapter\PromiseAdapterInterface`. (see [Overblog/Promise-Adapter](./lib/promise-adapter/docs/usage.md)) - *$options*: An optional object of options: - *batch*: Default `true`. Set to `false` to disable batching, instead @@ -163,7 +163,7 @@ list($a, $b) = DataLoader::await($myLoader->loadMany(['a', 'b'])); This is equivalent to the more verbose: -```js +```php list($a, $b) = DataLoader::await(\React\Promise\all([ $myLoader->load('a'), $myLoader->load('b') @@ -202,10 +202,8 @@ Await method process all waiting promise in all dataLoaderPHP instances. - *$unwrap*: controls whether or not the value of the promise is returned for a fulfilled promise or if an exception is thrown if the promise is rejected. Default `true`. -## Using with Webonyx/GraphQL [WIP] +## Using with Webonyx/GraphQL -A [PR](https://github.com/webonyx/graphql-php/pull/67) is open on [Webonyx/GraphQL](https://github.com/webonyx/graphql-php) -to supports DataLoaderPHP and more generally promise. Here [an example](https://github.com/mcg-web/sandbox-dataloader-graphql-php/blob/master/with-dataloader.php). ## Credits diff --git a/composer.json b/composer.json index b4f2f1a..450f0e4 100644 --- a/composer.json +++ b/composer.json @@ -1,24 +1,43 @@ { - "name": "overblog/dataloader-php", - "type": "library", - "license": "MIT", - "description": "DataLoaderPhp is a generic utility to be used as part of your application's data fetching layer to provide a simplified and consistent API over various remote data sources such as databases or web services via batching and caching.", - "keywords": ["dataLoader", "caching", "batching"], - "autoload": { - "psr-4": { - "Overblog\\DataLoader\\": "src/" - } - }, - "autoload-dev": { - "psr-4": { - "Overblog\\DataLoader\\Tests\\": "tests/" - } - }, - "require": { - "php": "^5.5|^7.0", - "mcg-web/promise-factory": "^0.2" - }, - "require-dev": { - "phpunit/phpunit": "^4.1|^5.1" + "name": "overblog/dataloader-php", + "type": "library", + "license": "MIT", + "description": "DataLoaderPhp is a generic utility to be used as part of your application's data fetching layer to provide a simplified and consistent API over various remote data sources such as databases or web services via batching and caching.", + "keywords": ["dataLoader", "caching", "batching"], + "config" : { + "bin-dir": "bin", + "sort-packages": true + }, + "autoload": { + "psr-4": { + "Overblog\\DataLoader\\": "src/", + "Overblog\\PromiseAdapter\\": "lib/promise-adapter/src/" } + }, + "autoload-dev": { + "psr-4": { + "Overblog\\DataLoader\\Test\\": "tests/", + "Overblog\\PromiseAdapter\\Test\\": "lib/promise-adapter/tests/" + } + }, + "replace": { + "overblog/promise-adapter": "self.version" + }, + "require": { + "php": "^5.5|^7.0" + }, + "require-dev": { + "guzzlehttp/promises": "^1.3.0", + "phpunit/phpunit": "^4.1|^5.1", + "react/promise": "^2.5.0" + }, + "suggest": { + "guzzlehttp/promises": "To use with Guzzle promise", + "react/promise": "To use with ReactPhp promise" + }, + "extra": { + "branch-alias": { + "dev-master": "0.3-dev" + } + } } diff --git a/lib/promise-adapter/.gitignore b/lib/promise-adapter/.gitignore new file mode 100644 index 0000000..67da7a1 --- /dev/null +++ b/lib/promise-adapter/.gitignore @@ -0,0 +1,5 @@ +/vendor/ +composer.lock +composer.phar +phpunit.xml +/bin diff --git a/lib/promise-adapter/.travis.yml b/lib/promise-adapter/.travis.yml new file mode 100644 index 0000000..c382761 --- /dev/null +++ b/lib/promise-adapter/.travis.yml @@ -0,0 +1,33 @@ +language: php + +php: + - 5.5 + - 5.6 + - 7.0 + - 7.1 + - nightly + - hhvm + +branches: + only: + - master + - /^\d+\.\d+$/ + +matrix: + allow_failures: + - php: nightly + +cache: + directories: + - $HOME/.composer/cache + +before_install: + - if [[ "$TRAVIS_PHP_VERSION" != "5.6" && "$TRAVIS_PHP_VERSION" != "hhvm" ]]; then phpenv config-rm xdebug.ini || true; fi + - composer selfupdate + +install: composer update --prefer-dist --no-interaction + +script: if [ "$TRAVIS_PHP_VERSION" == "5.6" ]; then bin/phpunit --debug --coverage-clover build/logs/clover.xml; else bin/phpunit --debug; fi + +after_success: + - if [ "$TRAVIS_PHP_VERSION" == "5.6" ]; then composer require "satooshi/php-coveralls:^1.0" && travis_retry php bin/coveralls -v; fi diff --git a/lib/promise-adapter/LICENSE b/lib/promise-adapter/LICENSE new file mode 100644 index 0000000..7f9b2d6 --- /dev/null +++ b/lib/promise-adapter/LICENSE @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) Overblog + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/lib/promise-adapter/README.md b/lib/promise-adapter/README.md new file mode 100644 index 0000000..a45d519 --- /dev/null +++ b/lib/promise-adapter/README.md @@ -0,0 +1,26 @@ +# PromiseAdapter + +This library tries to create a simple promise adapter standard while waiting for a psr. +It Comes out of the box with adapter for [ReactPhp/Promise](https://github.com/reactphp/promise) and +[Guzzle/Promises](https://github.com/guzzle/promises). + +[![Build Status](https://travis-ci.org/overblog/promise-adapter.svg?branch=master)](https://travis-ci.org/overblog/promise-adapter) +[![Coverage Status](https://coveralls.io/repos/github/overblog/promise-adapter/badge.svg?branch=master)](https://coveralls.io/github/overblog/promise-adapter?branch=master) +[![Latest Stable Version](https://poser.pugx.org/overblog/promise-adapter/version)](https://packagist.org/packages/overblog/promise-adapter) +[![License](https://poser.pugx.org/overblog/promise-adapter/license)](https://packagist.org/packages/overblog/promise-adapter) + +## Installation + +First, install PromiseAdapter using composer. + +```sh +composer require "overblog/promise-adapter" +``` + +# Usage + +see [here](./docs/usage.md) + +## License + +Overblog/PromiseAdapter is released under the [MIT](https://github.com/overblog/promise-adapter/blob/master/LICENSE) license. diff --git a/lib/promise-adapter/composer.json b/lib/promise-adapter/composer.json new file mode 100644 index 0000000..dcbbdf3 --- /dev/null +++ b/lib/promise-adapter/composer.json @@ -0,0 +1,38 @@ +{ + "name": "overblog/promise-adapter", + "description": "This library tries to create a simple promise adapter standard while waiting for a psr.", + "type": "library", + "keywords": [ + "promise", + "adapter", + "guzzle", + "react" + ], + "config" : { + "bin-dir": "bin", + "sort-packages": true + }, + "autoload": { + "psr-4": { + "Overblog\\PromiseAdapter\\": "src/" + } + }, + "autoload-dev": { + "psr-4": { + "Overblog\\PromiseAdapter\\Test\\": "tests/" + } + }, + "require": { + "php": "^5.5|^7.0" + }, + "require-dev": { + "guzzlehttp/promises": "^1.3.0", + "phpunit/phpunit": "^4.1|^5.1", + "react/promise": "^2.5.0" + }, + "suggest": { + "guzzlehttp/promises": "To use with Guzzle promise", + "react/promise": "To use with ReactPhp promise" + }, + "license": "MIT" +} diff --git a/lib/promise-adapter/docs/usage.md b/lib/promise-adapter/docs/usage.md new file mode 100644 index 0000000..82bc6ec --- /dev/null +++ b/lib/promise-adapter/docs/usage.md @@ -0,0 +1,23 @@ +# Promise adapter usage + +## Optional requirements + +Optional to use Guzzle: + +```sh +composer require "guzzlehttp/promises" +``` + +Optional to use ReactPhp: + +```sh +composer require "react/promise" +``` + +## Supported Adapter + +*Guzzle*: `Overblog\PromiseAdapter\Adapter\GuzzleHttpPromiseAdapter` + +*ReactPhp*: `Overblog\PromiseAdapter\Adapter\ReactPromiseAdapter` + +To use a custom Promise lib you can implement `Overblog\PromiseAdapter\PromiseAdapterInterface` diff --git a/lib/promise-adapter/phpunit.xml.dist b/lib/promise-adapter/phpunit.xml.dist new file mode 100644 index 0000000..bee8e77 --- /dev/null +++ b/lib/promise-adapter/phpunit.xml.dist @@ -0,0 +1,29 @@ + + + + + + + + + + + ./tests + + + + + + ./src + + ./vendor + ./tests + + + + diff --git a/lib/promise-adapter/src/Adapter/GuzzleHttpPromiseAdapter.php b/lib/promise-adapter/src/Adapter/GuzzleHttpPromiseAdapter.php new file mode 100644 index 0000000..def124e --- /dev/null +++ b/lib/promise-adapter/src/Adapter/GuzzleHttpPromiseAdapter.php @@ -0,0 +1,135 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Overblog\PromiseAdapter\Adapter; + +use GuzzleHttp\Promise\FulfilledPromise; +use GuzzleHttp\Promise\Promise; +use GuzzleHttp\Promise\PromiseInterface; +use GuzzleHttp\Promise\RejectedPromise; +use Overblog\PromiseAdapter\PromiseAdapterInterface; + +class GuzzleHttpPromiseAdapter implements PromiseAdapterInterface +{ + /** + * {@inheritdoc} + * + * @return Promise + */ + public function create(&$resolve = null, &$reject = null, callable $canceller = null) + { + $queue = \GuzzleHttp\Promise\queue(); + $promise = new Promise([$queue, 'run'], $canceller); + + $reject = [$promise, 'reject']; + $resolve = [$promise, 'resolve']; + + return $promise; + } + + /** + * {@inheritdoc} + * + * @return FulfilledPromise a full filed Promise + */ + public function createFulfilled($promiseOrValue = null) + { + $promise = \GuzzleHttp\Promise\promise_for($promiseOrValue); + + return $promise; + } + + /** + * {@inheritdoc} + * + * @return RejectedPromise a rejected promise + */ + public function createRejected($reason) + { + $promise = \GuzzleHttp\Promise\rejection_for($reason); + + return $promise; + } + + /** + * {@inheritdoc} + * + * @return Promise + */ + public function createAll($promisesOrValues) + { + $promise = empty($promisesOrValues) ? $this->createFulfilled($promisesOrValues) : \GuzzleHttp\Promise\all($promisesOrValues); + + return $promise; + } + + /** + * {@inheritdoc} + */ + public function isPromise($value, $strict = false) + { + $isStrictPromise = $value instanceof PromiseInterface; + + if ($strict) { + return $isStrictPromise; + } + + return $isStrictPromise || is_callable([$value, 'then']); + } + + /** + * {@inheritdoc} + */ + public function await($promise = null, $unwrap = false) + { + $resolvedValue = null; + + if (null !== $promise) { + $exception = null; + if (!static::isPromise($promise)) { + throw new \InvalidArgumentException(sprintf('The "%s" method must be called with a Promise ("then" method).', __METHOD__)); + } + + /** @var Promise $promise */ + $promise->then(function ($values) use (&$resolvedValue) { + $resolvedValue = $values; + }, function ($reason) use (&$exception) { + $exception = $reason; + }); + \GuzzleHttp\Promise\queue()->run(); + + if ($exception instanceof \Exception) { + if (!$unwrap) { + return $exception; + } + throw $exception; + } + } else { + \GuzzleHttp\Promise\queue()->run(); + } + + return $resolvedValue; + } + + /** + * Cancel a promise + * + * @param PromiseInterface $promise + * {@inheritdoc} + */ + public function cancel($promise) + { + if (!static::isPromise($promise, true)) { + throw new \InvalidArgumentException(sprintf('The "%s" method must be called with a compatible Promise.', __METHOD__)); + } + $promise->cancel(); + } +} diff --git a/lib/promise-adapter/src/Adapter/ReactPromiseAdapter.php b/lib/promise-adapter/src/Adapter/ReactPromiseAdapter.php new file mode 100644 index 0000000..aabc19f --- /dev/null +++ b/lib/promise-adapter/src/Adapter/ReactPromiseAdapter.php @@ -0,0 +1,130 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Overblog\PromiseAdapter\Adapter; + +use Overblog\PromiseAdapter\PromiseAdapterInterface; +use React\Promise\CancellablePromiseInterface; +use React\Promise\Deferred; +use React\Promise\FulfilledPromise; +use React\Promise\Promise; +use React\Promise\PromiseInterface; +use React\Promise\RejectedPromise; + +class ReactPromiseAdapter implements PromiseAdapterInterface +{ + /** + * {@inheritdoc} + * + * @return Promise + */ + public function create(&$resolve = null, &$reject = null, callable $canceller = null) + { + $deferred = new Deferred($canceller); + + $reject = [$deferred, 'reject']; + $resolve = [$deferred, 'resolve']; + + return $deferred->promise(); + } + + /** + * {@inheritdoc} + * + * @return FulfilledPromise a full filed Promise + */ + public function createFulfilled($promiseOrValue = null) + { + return \React\Promise\resolve($promiseOrValue); + } + + /** + * {@inheritdoc} + * + * @return RejectedPromise a rejected promise + */ + public function createRejected($reason) + { + return \React\Promise\reject($reason); + } + + /** + * {@inheritdoc} + * + * @return Promise + */ + public function createAll($promisesOrValues) + { + return \React\Promise\all($promisesOrValues); + } + + /** + * {@inheritdoc} + */ + public function isPromise($value, $strict = false) + { + $isStrictPromise = $value instanceof PromiseInterface; + + if ($strict) { + return $isStrictPromise; + } + + return $isStrictPromise || is_callable([$value, 'then']); + } + + /** + * {@inheritdoc} + */ + public function await($promise = null, $unwrap = false) + { + if (null === $promise) { + return null; + } + $wait = true; + $resolvedValue = null; + $exception = null; + if (!static::isPromise($promise)) { + throw new \InvalidArgumentException(sprintf('The "%s" method must be called with a Promise ("then" method).', __METHOD__)); + } + $promise->then(function ($values) use (&$resolvedValue, &$wait) { + $resolvedValue = $values; + $wait = false; + }, function ($reason) use (&$exception, &$wait) { + $exception = $reason; + $wait = false; + }); + + while ($wait) { + } + + if ($exception instanceof \Exception) { + if (!$unwrap) { + return $exception; + } + throw $exception; + } + + return $resolvedValue; + } + + /** + * Cancel a promise + * + * @param CancellablePromiseInterface $promise + */ + public function cancel($promise) + { + if (!$promise instanceof CancellablePromiseInterface) { + throw new \InvalidArgumentException(sprintf('The "%s" method must be called with a compatible Promise.', __METHOD__)); + } + $promise->cancel(); + } +} diff --git a/lib/promise-adapter/src/PromiseAdapterInterface.php b/lib/promise-adapter/src/PromiseAdapterInterface.php new file mode 100644 index 0000000..6517a9e --- /dev/null +++ b/lib/promise-adapter/src/PromiseAdapterInterface.php @@ -0,0 +1,81 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Overblog\PromiseAdapter; + +interface PromiseAdapterInterface +{ + /** + * Creates a Promise + * + * @param $resolve + * @param $reject + * @param callable $canceller + * + * @return mixed a Promise + */ + public function create(&$resolve = null, &$reject = null, callable $canceller = null); + + /** + * Creates a full filed Promise for a value if the value is not a promise. + * + * @param mixed $promiseOrValue + * + * @return mixed a full filed Promise + */ + public function createFulfilled($promiseOrValue = null); + + /** + * Creates a rejected promise for a reason if the reason is not a promise. If + * the provided reason is a promise, then it is returned as-is. + * + * @param mixed $reason + * + * @return mixed a rejected promise + */ + public function createRejected($reason); + + /** + * Given an array of promises, return a promise that is fulfilled when all the + * items in the array are fulfilled. + * + * @param mixed $promisesOrValues Promises or values. + * + * @return mixed a Promise + */ + public function createAll($promisesOrValues); + + /** + * Check if value is a promise + * + * @param mixed $value + * @param bool $strict + * + * @return bool + */ + public function isPromise($value, $strict = false); + + /** + * Cancel a promise + * + * @param $promise + */ + public function cancel($promise); + + /** + * wait for Promise to complete + * @param mixed $promise + * @param bool $unwrap + * + * @return mixed + */ + public function await($promise = null, $unwrap = false); +} diff --git a/lib/promise-adapter/tests/AdapterTest.php b/lib/promise-adapter/tests/AdapterTest.php new file mode 100644 index 0000000..f9d2119 --- /dev/null +++ b/lib/promise-adapter/tests/AdapterTest.php @@ -0,0 +1,217 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + + +namespace Overblog\PromiseAdapter\Tests; + +use Overblog\PromiseAdapter\Adapter\GuzzleHttpPromiseAdapter; +use Overblog\PromiseAdapter\Adapter\ReactPromiseAdapter; +use Overblog\PromiseAdapter\PromiseAdapterInterface; + +class AdapterTest extends \PHPUnit_Framework_TestCase +{ + /** + * @dataProvider AdapterDataProvider + * @param string $promiseClass + * @param PromiseAdapterInterface $Adapter + * @param string $context + */ + public function testCreate(PromiseAdapterInterface $Adapter, $context, $promiseClass) + { + $promise = $Adapter->create($resolve, $reject); + + $this->assertInstanceOf($promiseClass, $promise, $context); + $this->assertTrue(is_callable($resolve), $context); + $this->assertTrue(is_callable($reject), $context); + } + + /** + * @dataProvider AdapterDataProvider + * @param PromiseAdapterInterface $Adapter + * @param $message + */ + public function testResolveCreatedPromise(PromiseAdapterInterface $Adapter, $message) + { + $promise = $Adapter->create($resolve, $reject); + $expectResolvedValue = 'Resolve value'; + $resolve($expectResolvedValue); + $resolvedValue = $Adapter->await($promise); + + $this->assertEquals($expectResolvedValue, $resolvedValue, $message); + } + + /** + * @dataProvider AdapterDataProvider + * @param PromiseAdapterInterface $Adapter + * @param string $context + */ + public function testRejectCreatedPromise(PromiseAdapterInterface $Adapter, $context) + { + $promise = $Adapter->create($resolve, $reject); + + $expectRejectionReason = new \Exception('Error!'); + $reject($expectRejectionReason); + + $rejectionReason = $Adapter->await($promise, false); + $this->assertEquals($expectRejectionReason, $rejectionReason, $context); + } + + /** + * @dataProvider AdapterDataProvider + * @param PromiseAdapterInterface $Adapter + * @param string $context + * @param string $promiseClass + */ + public function testCreateAll(PromiseAdapterInterface $Adapter, $context, $promiseClass) + { + $values = ['A', 'B', 'C']; + $promise = $Adapter->createAll($values); + $this->assertInstanceOf($promiseClass, $promise, $context); + + $resolvedValue = $Adapter->await($promise); + + $this->assertEquals($values, $resolvedValue, $context); + } + + /** + * @dataProvider AdapterDataProvider + * @param PromiseAdapterInterface $Adapter + * @param string $context + * @param string $promiseClass + */ + public function testCreateFulfilled(PromiseAdapterInterface $Adapter, $context, $promiseClass) + { + $value = 'resolved!'; + $promise = $Adapter->createFulfilled($value); + $this->assertInstanceOf($promiseClass, $promise, $context); + + $resolvedValue = $Adapter->await($promise); + $this->assertEquals($value, $resolvedValue, $context); + } + + /** + * @dataProvider AdapterDataProvider + * @param PromiseAdapterInterface $Adapter + * @param string $context + * @param string $promiseClass + */ + public function testCreatedRejected(PromiseAdapterInterface $Adapter, $context, $promiseClass) + { + $expectRejectionReason = new \Exception('Error!'); + $promise = $Adapter->createRejected($expectRejectionReason); + $this->assertInstanceOf($promiseClass, $promise, $context); + + $rejectionReason = $Adapter->await($promise, false); + $this->assertEquals($expectRejectionReason, $rejectionReason, $context); + } + + /** + * @dataProvider AdapterDataProvider + * @param PromiseAdapterInterface $Adapter + * @param string $context + */ + public function testIsPromise(PromiseAdapterInterface $Adapter, $context) + { + $promise = $Adapter->create(); + + $this->assertTrue($Adapter->isPromise($promise, true), $context); + $this->assertFalse($Adapter->isPromise([]), $context); + $this->assertFalse($Adapter->isPromise(new \stdClass()), $context); + } + + /** + * @dataProvider AdapterDataProvider + * @param PromiseAdapterInterface $Adapter + * @param string $context + */ + public function testAwaitWithoutPromise(PromiseAdapterInterface $Adapter, $context) + { + $expected = 'expected value'; + $promise = $Adapter->createFulfilled($expected); + $actual = null; + + $promise->then(function ($value) use (&$actual) { + $actual = $value; + }); + + $Adapter->await(); + + $this->assertEquals($expected, $actual, $context); + } + + /** + * @dataProvider AdapterDataProvider + * @param PromiseAdapterInterface $Adapter + * + * @expectedException \Exception + * @expectedExceptionMessage error! + */ + public function testAwaitWithUnwrap(PromiseAdapterInterface $Adapter) + { + $expected = new \Exception('error!'); + $promise = $Adapter->createRejected($expected); + + $Adapter->await($promise, true); + } + + /** + * @dataProvider AdapterDataProvider + * @param PromiseAdapterInterface $Adapter + * + * @expectedException \InvalidArgumentException + * @expectedExceptionMessage ::await" method must be called with a Promise ("then" method). + */ + public function testAwaitWithInvalidPromise(PromiseAdapterInterface $Adapter) + { + $Adapter->await(new \stdClass(), true); + } + + /** + * @dataProvider AdapterDataProvider + * @param PromiseAdapterInterface $Adapter + * + * @expectedException \Exception + * @expectedExceptionMessage Cancel promise! + */ + public function testCancel(PromiseAdapterInterface $Adapter) + { + $promise = $Adapter->create($resolve, $reject, function () { + throw new \Exception('Cancel promise!'); + }); + + $Adapter->cancel($promise); + $Adapter->await($promise, true); + } + + /** + * @dataProvider AdapterDataProvider + * @param PromiseAdapterInterface $Adapter + * + * @expectedException \Exception + * @expectedExceptionMessage ::cancel" method must be called with a compatible Promise. + */ + public function testCancelInvalidPromise(PromiseAdapterInterface $Adapter) + { + $Adapter->create($resolve, $reject, function () { + throw new \Exception('Cancel will never be called!'); + }); + + $Adapter->cancel(new \stdClass()); + } + + public function AdapterDataProvider() + { + return [ + [new GuzzleHttpPromiseAdapter(), 'guzzle', '\\GuzzleHttp\\Promise\\PromiseInterface'], + [new ReactPromiseAdapter(), 'react', '\\React\\Promise\\PromiseInterface'], + ]; + } +} diff --git a/phpunit.xml.dist b/phpunit.xml.dist index 89cb76e..14c5b99 100644 --- a/phpunit.xml.dist +++ b/phpunit.xml.dist @@ -14,15 +14,18 @@ ./tests + ./lib/promise-adapter/tests ./src + ./lib/promise-adapter/src ./vendor ./tests + ./lib/promise-adapter/tests diff --git a/src/DataLoader.php b/src/DataLoader.php index 28642cd..a46b249 100644 --- a/src/DataLoader.php +++ b/src/DataLoader.php @@ -11,7 +11,7 @@ namespace Overblog\DataLoader; -use McGWeb\PromiseFactory\PromiseFactoryInterface; +use Overblog\PromiseAdapter\PromiseAdapterInterface; class DataLoader { @@ -41,14 +41,14 @@ class DataLoader private static $instances = []; /** - * @var PromiseFactoryInterface + * @var PromiseAdapterInterface */ - private $promiseFactory; + private $promiseAdapter; - public function __construct(callable $batchLoadFn, PromiseFactoryInterface $promiseFactory, Option $options = null) + public function __construct(callable $batchLoadFn, PromiseAdapterInterface $promiseFactory, Option $options = null) { $this->batchLoadFn = $batchLoadFn; - $this->promiseFactory = $promiseFactory; + $this->promiseAdapter = $promiseFactory; $this->options = $options ?: new Option(); $this->promiseCache = $this->options->getCacheMap(); self::$instances[] = $this; @@ -78,7 +78,7 @@ public function load($key) } // Otherwise, produce a new Promise for this value. - $promise = $this->getPromiseFactory()->create( + $promise = $this->getPromiseAdapter()->create( $resolve, $reject, function () { @@ -132,7 +132,7 @@ public function loadMany($keys) if (!is_array($keys) && !$keys instanceof \Traversable) { throw new \InvalidArgumentException(sprintf('The "%s" method must be called with Array but got: %s.', __METHOD__, gettype($keys))); } - return $this->getPromiseFactory()->createAll(array_map( + return $this->getPromiseAdapter()->createAll(array_map( function ($key) { return $this->load($key); }, @@ -185,7 +185,7 @@ public function prime($key, $value) if (!$this->promiseCache->has($cacheKey)) { // Cache a rejected promise if the value is an Error, in order to match // the behavior of load(key). - $promise = $value instanceof \Exception ? $this->getPromiseFactory()->createReject($value) : $this->getPromiseFactory()->createResolve($value); + $promise = $value instanceof \Exception ? $this->getPromiseAdapter()->createRejected($value) : $this->getPromiseAdapter()->createFulfilled($value); $this->promiseCache->set($cacheKey, $promise); } @@ -198,7 +198,7 @@ public function __destruct() if ($this->needProcess()) { foreach ($this->queue as $data) { try { - $this->getPromiseFactory()->cancel($data['promise']); + $this->getPromiseAdapter()->cancel($data['promise']); } catch (\Exception $e) { // no need to do nothing if cancel failed } @@ -221,14 +221,14 @@ protected function needProcess() protected function process() { if ($this->needProcess()) { - $this->getPromiseFactory()->await(); + $this->getPromiseAdapter()->await(); $this->dispatchQueue(); } } - protected function getPromiseFactory() + protected function getPromiseAdapter() { - return $this->promiseFactory; + return $this->promiseAdapter; } /** @@ -244,7 +244,7 @@ public static function await($promise = null, $unwrap = true) } self::awaitInstances(); - return self::$instances[0]->getPromiseFactory()->await($promise, $unwrap); + return self::$instances[0]->getPromiseAdapter()->await($promise, $unwrap); } private static function awaitInstances() @@ -371,7 +371,7 @@ function ($values) use ($keys, $queue) { } }; } - )->otherwise(function ($error) use ($queue) { + )->then(null, function ($error) use ($queue) { $this->failedDispatch($queue, $error); }); } diff --git a/tests/AbuseTest.php b/tests/AbuseTest.php index 41580f9..f771a98 100644 --- a/tests/AbuseTest.php +++ b/tests/AbuseTest.php @@ -9,7 +9,7 @@ * file that was distributed with this source code. */ -namespace Overblog\DataLoader\Tests; +namespace Overblog\DataLoader\Test; use Overblog\DataLoader\DataLoader; @@ -75,7 +75,7 @@ public function testBatchFunctionMustReturnAPromiseNotAValue() public function testBatchFunctionMustReturnAPromiseOfAnArrayNotNull() { DataLoader::await(self::idLoader(function () { - return self::$promiseFactory->createResolve(null); + return self::$promiseAdapter->createFulfilled(null); })->load(1)); } @@ -87,7 +87,7 @@ public function testBatchFunctionMustReturnAPromiseOfAnArrayNotNull() public function testBatchFunctionMustPromiseAnArrayOfCorrectLength() { DataLoader::await(self::idLoader(function () { - return self::$promiseFactory->createResolve([]); + return self::$promiseAdapter->createFulfilled([]); })->load(1)); } @@ -122,10 +122,10 @@ private static function idLoader(callable $batchLoadFn = null) { if (null === $batchLoadFn) { $batchLoadFn = function ($keys) { - return self::$promiseFactory->createAll($keys); + return self::$promiseAdapter->createAll($keys); }; } - return new DataLoader($batchLoadFn, self::$promiseFactory); + return new DataLoader($batchLoadFn, self::$promiseAdapter); } } diff --git a/tests/DataLoadTest.php b/tests/DataLoadTest.php index aadae6e..9371503 100644 --- a/tests/DataLoadTest.php +++ b/tests/DataLoadTest.php @@ -9,7 +9,7 @@ * file that was distributed with this source code. */ -namespace Overblog\DataLoader\Tests; +namespace Overblog\DataLoader\Test; use Overblog\DataLoader\DataLoader; use Overblog\DataLoader\Option; @@ -64,7 +64,7 @@ public function testBatchesMultipleRequests() $promise1 = $identityLoader->load(1); $promise2 = $identityLoader->load(2); - list($value1, $value2) = DataLoader::await(self::$promiseFactory->createAll([$promise1, $promise2])); + list($value1, $value2) = DataLoader::await(self::$promiseAdapter->createAll([$promise1, $promise2])); $this->assertEquals(1, $value1); $this->assertEquals(2, $value2); @@ -86,7 +86,7 @@ public function testBatchesMultipleRequestsWithMaxBatchSizes() $promise2 = $identityLoader->load(2); $promise3 = $identityLoader->load(3); - list($value1, $value2, $value3) = DataLoader::await(self::$promiseFactory->createAll([$promise1, $promise2, $promise3])); + list($value1, $value2, $value3) = DataLoader::await(self::$promiseAdapter->createAll([$promise1, $promise2, $promise3])); $this->assertEquals(1, $value1); $this->assertEquals(2, $value2); $this->assertEquals(3, $value3); @@ -110,7 +110,7 @@ public function testCoalescesIdenticalRequests() $this->assertTrue($promise1a === $promise1b); - list($value1a, $value1b) = DataLoader::await(self::$promiseFactory->createAll([$promise1a, $promise1b])); + list($value1a, $value1b) = DataLoader::await(self::$promiseAdapter->createAll([$promise1a, $promise1b])); $this->assertEquals(1, $value1a); $this->assertEquals(1, $value1b); @@ -128,17 +128,17 @@ public function testCachesRepeatedRequests() */ list($identityLoader, $loadCalls) = self::idLoader(); - list($a, $b) = DataLoader::await(self::$promiseFactory->createAll([$identityLoader->load('A'), $identityLoader->load('B')])); + list($a, $b) = DataLoader::await(self::$promiseAdapter->createAll([$identityLoader->load('A'), $identityLoader->load('B')])); $this->assertEquals('A', $a); $this->assertEquals('B', $b); $this->assertEquals([['A', 'B']], $loadCalls->getArrayCopy()); - list($a2, $c) = DataLoader::await(self::$promiseFactory->createAll([$identityLoader->load('A'), $identityLoader->load('C')])); + list($a2, $c) = DataLoader::await(self::$promiseAdapter->createAll([$identityLoader->load('A'), $identityLoader->load('C')])); $this->assertEquals('A', $a2); $this->assertEquals('C', $c); $this->assertEquals([['A', 'B'], ['C']], $loadCalls->getArrayCopy()); - list($a3, $b2, $c2) = DataLoader::await(self::$promiseFactory->createAll([$identityLoader->load('A'), $identityLoader->load('B'), $identityLoader->load('C')])); + list($a3, $b2, $c2) = DataLoader::await(self::$promiseAdapter->createAll([$identityLoader->load('A'), $identityLoader->load('B'), $identityLoader->load('C')])); $this->assertEquals('A', $a3); $this->assertEquals('B', $b2); $this->assertEquals('C', $c2); @@ -156,13 +156,13 @@ public function testClearsSingleValueInLoader() */ list($identityLoader, $loadCalls) = self::idLoader(); - list($a, $b) = DataLoader::await(self::$promiseFactory->createAll([$identityLoader->load('A'), $identityLoader->load('B')])); + list($a, $b) = DataLoader::await(self::$promiseAdapter->createAll([$identityLoader->load('A'), $identityLoader->load('B')])); $this->assertEquals('A', $a); $this->assertEquals('B', $b); $this->assertEquals([['A', 'B']], $loadCalls->getArrayCopy()); $identityLoader->clear('A'); - list($a2, $b2) = DataLoader::await(self::$promiseFactory->createAll([$identityLoader->load('A'), $identityLoader->load('B')])); + list($a2, $b2) = DataLoader::await(self::$promiseAdapter->createAll([$identityLoader->load('A'), $identityLoader->load('B')])); $this->assertEquals('A', $a2); $this->assertEquals('B', $b2); $this->assertEquals([['A', 'B'], ['A']], $loadCalls->getArrayCopy()); @@ -179,13 +179,13 @@ public function testClearsAllValuesInLoader() */ list($identityLoader, $loadCalls) = self::idLoader(); - list($a, $b) = DataLoader::await(self::$promiseFactory->createAll([$identityLoader->load('A'), $identityLoader->load('B')])); + list($a, $b) = DataLoader::await(self::$promiseAdapter->createAll([$identityLoader->load('A'), $identityLoader->load('B')])); $this->assertEquals('A', $a); $this->assertEquals('B', $b); $this->assertEquals([['A', 'B']], $loadCalls->getArrayCopy()); $identityLoader->clearAll(); - list($a2, $b2) = DataLoader::await(self::$promiseFactory->createAll([$identityLoader->load('A'), $identityLoader->load('B')])); + list($a2, $b2) = DataLoader::await(self::$promiseAdapter->createAll([$identityLoader->load('A'), $identityLoader->load('B')])); $this->assertEquals('A', $a2); $this->assertEquals('B', $b2); $this->assertEquals([['A', 'B'], ['A', 'B']], $loadCalls->getArrayCopy()); @@ -203,7 +203,7 @@ public function testAllowsPrimingTheCache() list($identityLoader, $loadCalls) = self::idLoader(); $identityLoader->prime('A', 'A'); - list($a, $b) = DataLoader::await(self::$promiseFactory->createAll([$identityLoader->load('A'), $identityLoader->load('B')])); + list($a, $b) = DataLoader::await(self::$promiseAdapter->createAll([$identityLoader->load('A'), $identityLoader->load('B')])); $this->assertEquals('A', $a); $this->assertEquals('B', $b); $this->assertEquals([['B']], $loadCalls->getArrayCopy()); @@ -423,7 +423,7 @@ public function testPropagatesErrorToAllLoads() * @var \ArrayObject $loadCalls */ list($failLoader, $loadCalls) = self::idLoader(null, function () { - return self::$promiseFactory->createReject(new \Exception('I am a terrible loader')); + return self::$promiseAdapter->createRejected(new \Exception('I am a terrible loader')); }); $promise1 = $failLoader->load(1); @@ -463,7 +463,7 @@ public function testAcceptsObjectsAsKeys() $keyA = new \stdClass(); $keyB = new \stdClass(); - list($valueA, $valueB) = DataLoader::await(self::$promiseFactory->createAll([$identityLoader->load($keyA), $identityLoader->load($keyB)])); + list($valueA, $valueB) = DataLoader::await(self::$promiseAdapter->createAll([$identityLoader->load($keyA), $identityLoader->load($keyB)])); $this->assertEquals($keyA, $valueA); $this->assertEquals($keyB, $valueB); @@ -476,7 +476,7 @@ public function testAcceptsObjectsAsKeys() // Caching $identityLoader->clear($keyA); - list($valueA2, $valueB2) = DataLoader::await(self::$promiseFactory->createAll([$identityLoader->load($keyA), $identityLoader->load($keyB)])); + list($valueA2, $valueB2) = DataLoader::await(self::$promiseAdapter->createAll([$identityLoader->load($keyA), $identityLoader->load($keyB)])); $this->assertEquals($keyA, $valueA2); $this->assertEquals($keyB, $valueB2); @@ -502,7 +502,7 @@ public function testMayDisableBatching() $promise1 = $identityLoader->load(1); $promise2 = $identityLoader->load(2); - list($value1, $value2) = DataLoader::await(self::$promiseFactory->createAll([$promise1, $promise2])); + list($value1, $value2) = DataLoader::await(self::$promiseAdapter->createAll([$promise1, $promise2])); $this->assertEquals(1, $value1); $this->assertEquals(2, $value2); @@ -522,17 +522,17 @@ public function testMayDisableCaching() */ list($identityLoader, $loadCalls) = self::idLoader(new Option(['cache' => false])); - list($a, $b) = DataLoader::await(self::$promiseFactory->createAll([$identityLoader->load('A'), $identityLoader->load('B')])); + list($a, $b) = DataLoader::await(self::$promiseAdapter->createAll([$identityLoader->load('A'), $identityLoader->load('B')])); $this->assertEquals('A', $a); $this->assertEquals('B', $b); $this->assertEquals([['A', 'B']], $loadCalls->getArrayCopy()); - list($a2, $c) = DataLoader::await(self::$promiseFactory->createAll([$identityLoader->load('A'), $identityLoader->load('C')])); + list($a2, $c) = DataLoader::await(self::$promiseAdapter->createAll([$identityLoader->load('A'), $identityLoader->load('C')])); $this->assertEquals('A', $a2); $this->assertEquals('C', $c); $this->assertEquals([['A', 'B'], ['A', 'C']], $loadCalls->getArrayCopy()); - list($a3, $b2, $c2) = DataLoader::await(self::$promiseFactory->createAll([$identityLoader->load('A'), $identityLoader->load('B'), $identityLoader->load('C')])); + list($a3, $b2, $c2) = DataLoader::await(self::$promiseAdapter->createAll([$identityLoader->load('A'), $identityLoader->load('B'), $identityLoader->load('C')])); $this->assertEquals('A', $a3); $this->assertEquals('B', $b2); $this->assertEquals('C', $c2); @@ -650,13 +650,13 @@ public function testAcceptsACustomCacheMapImplementation() */ list($identityLoader, $loadCalls) = self::idLoader(new Option(['cacheMap' => $aCustomMap])); - list($valueA, $valueB1) = DataLoader::await(self::$promiseFactory->createAll([$identityLoader->load('a'), $identityLoader->load('b')])); + list($valueA, $valueB1) = DataLoader::await(self::$promiseAdapter->createAll([$identityLoader->load('a'), $identityLoader->load('b')])); $this->assertEquals('a', $valueA); $this->assertEquals('b', $valueB1); $this->assertEquals([['a', 'b']], $loadCalls->getArrayCopy()); $this->assertEquals(['a', 'b'], array_keys($aCustomMap->stash->getArrayCopy())); - list($valueC, $valueB2) = DataLoader::await(self::$promiseFactory->createAll([$identityLoader->load('c'), $identityLoader->load('b')])); + list($valueC, $valueB2) = DataLoader::await(self::$promiseAdapter->createAll([$identityLoader->load('c'), $identityLoader->load('b')])); $this->assertEquals('c', $valueC); $this->assertEquals('b', $valueB2); $this->assertEquals([['a', 'b'], ['c']], $loadCalls->getArrayCopy()); @@ -688,23 +688,23 @@ public function testBatchesLoadsOccurringWithinPromises() list($identityLoader, $loadCalls) = self::idLoader(); DataLoader::await( - self::$promiseFactory->createAll([ + self::$promiseAdapter->createAll([ $identityLoader->load('A'), - self::$promiseFactory->createResolve() + self::$promiseAdapter->createFulfilled() ->then(function () { - return self::$promiseFactory->createResolve(); + return self::$promiseAdapter->createFulfilled(); }) ->then(function () use ($identityLoader) { $identityLoader->load('B'); - self::$promiseFactory->createResolve() + self::$promiseAdapter->createFulfilled() ->then(function () use ($identityLoader) { - return self::$promiseFactory->createResolve(); + return self::$promiseAdapter->createFulfilled(); }) ->then(function () use ($identityLoader) { $identityLoader->load('C'); - self::$promiseFactory->createResolve() + self::$promiseAdapter->createFulfilled() ->then(function () { - return self::$promiseFactory->createResolve(); + return self::$promiseAdapter->createFulfilled(); }) ->then(function () use ($identityLoader) { $identityLoader->load('D'); @@ -746,7 +746,7 @@ public function testCanCallALoaderFromALoader() return $deepLoader->load($keys); }); - list($a1, $b1, $a2, $b2) = DataLoader::await(self::$promiseFactory->createAll([ + list($a1, $b1, $a2, $b2) = DataLoader::await(self::$promiseAdapter->createAll([ $aLoader->load('A1'), $bLoader->load('B1'), $aLoader->load('A2'), @@ -794,14 +794,14 @@ public function testAwaitAlsoAwaitsNewlyCreatedDataloaders() $first = new DataLoader(function ($values) use (&$firstComplete, &$secondComplete) { $second = new DataLoader(function ($values) use (&$secondComplete) { $secondComplete = true; - return self::$promiseFactory->createAll(['B']); - }, self::$promiseFactory); + return self::$promiseAdapter->createAll(['B']); + }, self::$promiseAdapter); $second->load('B'); $firstComplete = true; - return self::$promiseFactory->createAll(['A']); - }, self::$promiseFactory); + return self::$promiseAdapter->createAll(['A']); + }, self::$promiseAdapter); DataLoader::await($first->load('A')); @@ -824,7 +824,7 @@ public function cacheKey($key) private static function errorLoader() { return self::idLoader(null, function ($keys) { - return self::$promiseFactory->createResolve( + return self::$promiseAdapter->createFulfilled( array_map(function ($key) { return new \Exception("Error: $key"); }, $keys) @@ -836,7 +836,7 @@ private static function eventLoader() { return self::idLoader(null, function ($keys) { $loadCalls[] = $keys; - return self::$promiseFactory->createResolve( + return self::$promiseAdapter->createFulfilled( array_map(function ($key) { return $key % 2 === 0 ? $key : new \Exception("Odd: $key"); }, $keys) @@ -849,7 +849,7 @@ private static function idLoader(Option $options = null, callable $batchLoadFnCa $loadCalls = new \ArrayObject(); if (null === $batchLoadFnCallBack) { $batchLoadFnCallBack = function ($keys) { - return self::$promiseFactory->createResolve($keys); + return self::$promiseAdapter->createFulfilled($keys); }; } @@ -857,13 +857,13 @@ private static function idLoader(Option $options = null, callable $batchLoadFnCa $loadCalls[] = $keys; return $batchLoadFnCallBack($keys); - }, self::$promiseFactory, $options); + }, self::$promiseAdapter, $options); return [$identityLoader, $loadCalls]; } private function assertInstanceOfPromise($object) { - $this->assertTrue(self::$promiseFactory->isPromise($object, true)); + $this->assertTrue(self::$promiseAdapter->isPromise($object, true)); } } diff --git a/tests/SimpleMap.php b/tests/SimpleMap.php index 9bab880..6e1da88 100644 --- a/tests/SimpleMap.php +++ b/tests/SimpleMap.php @@ -9,7 +9,7 @@ * file that was distributed with this source code. */ -namespace Overblog\DataLoader\Tests; +namespace Overblog\DataLoader\Test; use Overblog\DataLoader\CacheMap; diff --git a/tests/TestCase.php b/tests/TestCase.php index ca4c69d..6cbba2e 100644 --- a/tests/TestCase.php +++ b/tests/TestCase.php @@ -9,21 +9,21 @@ * file that was distributed with this source code. */ -namespace Overblog\DataLoader\Tests; +namespace Overblog\DataLoader\Test; -use McGWeb\PromiseFactory\Factory\GuzzleHttpPromiseFactory; -use McGWeb\PromiseFactory\PromiseFactoryInterface; +use Overblog\PromiseAdapter\Adapter\GuzzleHttpPromiseAdapter; +use Overblog\PromiseAdapter\Adapter\ReactPromiseAdapter; +use Overblog\PromiseAdapter\PromiseAdapterInterface; class TestCase extends \PHPUnit_Framework_TestCase { /** - * @var PromiseFactoryInterface + * @var PromiseAdapterInterface */ - protected static $promiseFactory; + protected static $promiseAdapter; public function setUp() { - self::$promiseFactory = new GuzzleHttpPromiseFactory(); + self::$promiseAdapter = new ReactPromiseAdapter(); } - }