diff --git a/.github/workflows/continuous-integration.yml b/.github/workflows/continuous-integration.yml new file mode 100644 index 0000000..799014e --- /dev/null +++ b/.github/workflows/continuous-integration.yml @@ -0,0 +1,73 @@ +name: "Continuous Integration" + +on: + pull_request: + push: + schedule: + - cron: "0 0 1 * *" + +jobs: + phpunit: + name: "PHPUnit" + runs-on: "ubuntu-20.04" + + strategy: + matrix: + php-version: + - "7.3" + - "7.4" + - "8.0" + dependencies: + - "highest" + include: + - dependencies: "lowest" + php-version: "7.3" + + steps: + - name: "Checkout" + uses: "actions/checkout@v2" + with: + fetch-depth: 2 + + - name: "Install PHP" + uses: "shivammathur/setup-php@v2" + with: + php-version: "${{ matrix.php-version }}" + coverage: "pcov" + ini-values: "zend.assertions=1" + + - name: "Install dependencies with Composer" + uses: "ramsey/composer-install@v1" + with: + dependency-versions: "${{ matrix.dependencies }}" + + - name: "Run PHPUnit" + run: "vendor/bin/phpunit --coverage-clover=coverage.xml" + + - name: "Upload coverage file" + uses: "actions/upload-artifact@v2" + with: + name: "phpunit-${{ matrix.deps }}-${{ matrix.php-version }}.coverage" + path: "coverage.xml" + + upload_coverage: + name: "Upload coverage to Codecov" + runs-on: "ubuntu-20.04" + needs: + - "phpunit" + + steps: + - name: "Checkout" + uses: "actions/checkout@v2" + with: + fetch-depth: 2 + + - name: "Download coverage files" + uses: "actions/download-artifact@v2" + with: + path: "reports" + + - name: "Upload to Codecov" + uses: "codecov/codecov-action@v1" + with: + directory: reports diff --git a/.scrutinizer.yml b/.scrutinizer.yml deleted file mode 100644 index 5f9e672..0000000 --- a/.scrutinizer.yml +++ /dev/null @@ -1,32 +0,0 @@ -filter: - excluded_paths: [tests/*] -checks: - php: - code_rating: true - remove_extra_empty_lines: true - remove_php_closing_tag: true - remove_trailing_whitespace: true - fix_use_statements: - remove_unused: true - preserve_multiple: false - preserve_blanklines: true - order_alphabetically: true - fix_php_opening_tag: true - fix_linefeed: true - fix_line_ending: true - fix_identation_4spaces: true - fix_doc_comments: true -tools: - php_analyzer: true - php_code_coverage: false - php_code_sniffer: - config: - standard: PSR2 - filter: - paths: ['src'] - php_loc: - enabled: true - excluded_dirs: [vendor, tests] - php_cpd: - enabled: true - excluded_dirs: [vendor, tests] diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index d2408be..0000000 --- a/.travis.yml +++ /dev/null @@ -1,37 +0,0 @@ -language: php - -php: - - '5.6' - - '7.0' - - '7.1' - - '7.2' - - '7.3' - - '7.4' - - 'nightly' - -matrix: - include: - - php: '5.3' - dist: precise - - php: '5.4' - dist: trusty - - php: '5.5' - dist: trusty - allow_failures: - - php: 'nightly' - -before_script: - - travis_retry composer self-update - - travis_retry composer global require hirak/prestissimo - - travis_retry composer install --no-interaction --prefer-dist - - travis_retry phpenv rehash - -script: - - if [[ ${TRAVIS_PHP_VERSION:0:3} == "5.3" ]]; then composer require --dev symfony/polyfill-php54; fi - - if [[ $TRAVIS_PHP_VERSION = 5.5.* || $TRAVIS_PHP_VERSION = 5.6.* || $TRAVIS_PHP_VERSION = 7.* ]]; then composer require --dev php-coveralls/php-coveralls; fi - - if [[ $TRAVIS_PHP_VERSION = 5.5.* || $TRAVIS_PHP_VERSION = 5.6.* || $TRAVIS_PHP_VERSION = 7.* ]]; then ./vendor/bin/phpunit --coverage-clover build/logs/clover.xml; else ./vendor/bin/phpunit; fi - - ./vendor/bin/phpcs --standard=psr2 -n src/ - - mkdir -p build/logs - -after_script: - - php vendor/bin/php-coveralls -v diff --git a/README.md b/README.md index 1bb43b4..74aedf6 100644 --- a/README.md +++ b/README.md @@ -1,8 +1,6 @@ [![Latest Stable Version](https://poser.pugx.org/bentools/iterable-functions/v/stable)](https://packagist.org/packages/bentools/iterable-functions) -[![License](https://poser.pugx.org/bentools/iterable-functions/license)](https://packagist.org/packages/bentools/iterable-functions) -[![Build Status](https://img.shields.io/travis/bpolaszek/php-iterable-functions/master.svg?style=flat-square)](https://travis-ci.org/bpolaszek/php-iterable-functions) -[![Coverage Status](https://coveralls.io/repos/github/bpolaszek/php-iterable-functions/badge.svg?branch=master)](https://coveralls.io/github/bpolaszek/php-iterable-functions?branch=master) -[![Quality Score](https://img.shields.io/scrutinizer/g/bpolaszek/php-iterable-functions.svg?style=flat-square)](https://scrutinizer-ci.com/g/bpolaszek/php-iterable-functions) +[![GitHub Actions][GA master image]][GA master] +[![Code Coverage][Coverage image]][CodeCov Master] [![Total Downloads](https://poser.pugx.org/bentools/iterable-functions/downloads)](https://packagist.org/packages/bentools/iterable-functions) Iterable functions @@ -191,3 +189,8 @@ Unit tests ``` ./vendor/bin/phpunit ``` + +[CodeCov Master]: https://codecov.io/gh/bpolaszek/php-iterable-functions/branch/2.0.x-dev +[Coverage image]: https://codecov.io/gh/bpolaszek/php-iterable-functions/branch/2.0.x-dev/graph/badge.svg +[GA master]: https://github.com/bpolaszek/php-iterable-functions/actions?query=workflow%3A%22Continuous+Integration%22+branch%3A2.0.x-dev +[GA master image]: https://github.com/bpolaszek/php-iterable-functions/workflows/Continuous%20Integration/badge.svg diff --git a/composer.json b/composer.json index 31041a7..cca90ba 100644 --- a/composer.json +++ b/composer.json @@ -15,11 +15,11 @@ ] }, "require": { - "php": ">=5.3" + "php": "^7.3 || ^8.0" }, "require-dev": { - "phpunit/phpunit": "^4.0|^5.0|^6.0|^7.0", + "phpunit/phpunit": "^9", "squizlabs/php_codesniffer": "^2.0|^3.4", - "symfony/var-dumper": "@stable" + "symfony/var-dumper": "^5.2" } } diff --git a/phpunit.xml.dist b/phpunit.xml.dist index 9ca55d7..9247927 100644 --- a/phpunit.xml.dist +++ b/phpunit.xml.dist @@ -1,37 +1,21 @@ - - tests/TestIsIterable.php - tests/TestIterableToArray.php - tests/TestIterableToTraversable.php - tests/TestIterableFilter.php - tests/TestIterableMap.php - tests/TestIterableObject.php + tests - - - ./src - - src/iterable-map-php53.php - src/iterable-map-php55.php - - - + + + src + + diff --git a/src/iterable-functions.php b/src/iterable-functions.php index de15eeb..6fbdc9e 100644 --- a/src/iterable-functions.php +++ b/src/iterable-functions.php @@ -2,12 +2,41 @@ use BenTools\IterableFunctions\IterableObject; -if (version_compare(PHP_VERSION, '5.5') >= 0) { - include_once __DIR__ . '/iterable-map-php55.php'; -} else { - include_once __DIR__ . '/iterable-map-php53.php'; +if (!function_exists('iterable_map')) { + + /** + * Maps a callable to an iterable. + * + * @param iterable|array|\Traversable $iterable + * @param callable $map + * @return array|ArrayIterator + * @throws InvalidArgumentException + */ + function iterable_map($iterable, $map) + { + if (!is_iterable($iterable)) { + throw new \InvalidArgumentException( + sprintf('Expected array or Traversable, got %s', is_object($iterable) ? get_class($iterable) : gettype($iterable)) + ); + } + + // Cannot rely on callable type-hint on PHP 5.3 + if (null !== $map && !is_callable($map) && !$map instanceof Closure) { + throw new InvalidArgumentException( + sprintf('Expected callable, got %s', is_object($map) ? get_class($map) : gettype($map)) + ); + } + + if ($iterable instanceof Traversable) { + return new ArrayIterator(array_map($map, iterator_to_array($iterable))); + } + + return array_map($map, $iterable); + } + } + if (!function_exists('is_iterable')) { /** diff --git a/src/iterable-map-php53.php b/src/iterable-map-php53.php deleted file mode 100644 index 3918de9..0000000 --- a/src/iterable-map-php53.php +++ /dev/null @@ -1,35 +0,0 @@ - $value) { - yield $key => $map($value); - } - }; - - return $generator($iterable, $map); - } - - return array_map($map, $iterable); - } - -} diff --git a/tests/TestIsIterable.php b/tests/IsIterableTest.php similarity index 95% rename from tests/TestIsIterable.php rename to tests/IsIterableTest.php index 8426ed8..7449010 100644 --- a/tests/TestIsIterable.php +++ b/tests/IsIterableTest.php @@ -2,7 +2,7 @@ use PHPUnit\Framework\TestCase; -class TestIsIterable extends TestCase +final class IsIterableTest extends TestCase { public function testFunctionExists() diff --git a/tests/TestIterableFilter.php b/tests/IterableFilterTest.php similarity index 83% rename from tests/TestIterableFilter.php rename to tests/IterableFilterTest.php index cd9d22e..fdc2539 100644 --- a/tests/TestIterableFilter.php +++ b/tests/IterableFilterTest.php @@ -1,6 +1,8 @@ assertEquals(array(1 => 'bar'), iterable_to_array(iterable_filter($iterable, $filter))); } - /** - * @expectedException InvalidArgumentException - */ public function testInvalidIterable() { + $this->expectException(InvalidArgumentException::class); + $filter = function () { return true; }; iterable_filter('foo', $filter); } -} \ No newline at end of file +} diff --git a/tests/TestIterableMap.php b/tests/IterableMapTest.php similarity index 81% rename from tests/TestIterableMap.php rename to tests/IterableMapTest.php index 26d2811..0746827 100644 --- a/tests/TestIterableMap.php +++ b/tests/IterableMapTest.php @@ -1,6 +1,8 @@ assertEquals(array('FOO', 'BAR'), iterable_to_array(iterable_map($iterable, $map))); } - /** - * @expectedException InvalidArgumentException - */ public function testInvalidIterable() { + $this->expectException(InvalidArgumentException::class); + $filter = function () { return true; }; iterable_map('foo', $filter); } -} \ No newline at end of file +} diff --git a/tests/TestIterableObject.php b/tests/IterableObjectTest.php similarity index 96% rename from tests/TestIterableObject.php rename to tests/IterableObjectTest.php index ea43d00..5c09d8c 100644 --- a/tests/TestIterableObject.php +++ b/tests/IterableObjectTest.php @@ -1,6 +1,8 @@ assertInstanceOf('Traversable', $traversable); } - /** - * @expectedException InvalidArgumentException - */ public function testInvalidArgument() { + $this->expectException(InvalidArgumentException::class); + $string = 'foo'; iterable_to_traversable($string); - var_dump(iterable_to_traversable(array('foo', 'bar'))); } } diff --git a/tests/bootstrap.php b/tests/bootstrap.php new file mode 100644 index 0000000..b0ccdc7 --- /dev/null +++ b/tests/bootstrap.php @@ -0,0 +1,7 @@ +