From 9ee64d6625702c17ff1e7a42b4eae0c2ac7129ed Mon Sep 17 00:00:00 2001 From: Graham Campbell Date: Sun, 22 Aug 2021 19:50:20 +0100 Subject: [PATCH 1/2] More fixes for PHP 8.1 and setup CI again --- .gitattributes | 2 +- .github/workflows/tests.yml | 139 ++++++++++++++++++ .scrutinizer.yml | 24 --- .travis.yml | 60 -------- README.md | 3 +- ...lizeForInternalSerializableClassesPass.php | 5 +- phpunit.xml.dist | 12 +- tests/Mockery/ContainerTest.php | 66 +++++---- tests/PHP80/Php80LanguageFeaturesTest.php | 68 +++++---- tests/PHP81/Php81LanguageFeaturesTest.php | 83 +++++++++++ 10 files changed, 307 insertions(+), 155 deletions(-) create mode 100644 .github/workflows/tests.yml delete mode 100644 .scrutinizer.yml delete mode 100644 .travis.yml create mode 100644 tests/PHP81/Php81LanguageFeaturesTest.php diff --git a/.gitattributes b/.gitattributes index db3bfc6e7..3fbfecd6e 100644 --- a/.gitattributes +++ b/.gitattributes @@ -1,5 +1,6 @@ * text=auto +/.github export-ignore /docker export-ignore /tests export-ignore .gitattributes export-ignore @@ -7,6 +8,5 @@ .php_cs export-ignore .scrutinizer.yml export-ignore .styleci.yml export-ignore -.travis.yml export-ignore Makefile export-ignore phpunit.xml.dist export-ignore diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml new file mode 100644 index 000000000..a981d6202 --- /dev/null +++ b/.github/workflows/tests.yml @@ -0,0 +1,139 @@ +name: Tests + +on: + push: + pull_request: + +jobs: + php5: + name: PHP ${{ matrix.php }} + runs-on: ubuntu-20.04 + + strategy: + matrix: + php: ['5.6'] + + steps: + - name: Checkout Code + uses: actions/checkout@v2 + + - name: Setup PHP + uses: shivammathur/setup-php@v2 + with: + php-version: ${{ matrix.php }} + tools: composer:v2 + extensions: mongodb, redis + coverage: xdebug + + - name: Setup Problem Matchers + run: echo "::add-matcher::${{ runner.tool_cache }}/phpunit.json" + + - name: Install Dependencies + uses: nick-invision/retry@v1 + with: + timeout_minutes: 5 + max_attempts: 5 + command: composer update --no-interaction --no-progress + + - name: Execute PHPUnit + run: vendor/bin/phpunit --coverage-text --testsuite="Mockery Test Suite PHP5" + + php7: + name: PHP ${{ matrix.php }} + runs-on: ubuntu-20.04 + + strategy: + matrix: + php: ['7.0', '7.1', '7.2', '7.3', '7.4'] + + steps: + - name: Checkout Code + uses: actions/checkout@v2 + + - name: Setup PHP + uses: shivammathur/setup-php@v2 + with: + php-version: ${{ matrix.php }} + tools: composer:v2 + extensions: mongodb, redis + coverage: xdebug + + - name: Setup Problem Matchers + run: echo "::add-matcher::${{ runner.tool_cache }}/phpunit.json" + + - name: Install Dependencies + uses: nick-invision/retry@v1 + with: + timeout_minutes: 5 + max_attempts: 5 + command: composer update --no-interaction --no-progress + + - name: Execute PHPUnit + run: vendor/bin/phpunit --coverage-text --testsuite="Mockery Test Suite PHP7" + + php80: + name: PHP ${{ matrix.php }} + runs-on: ubuntu-20.04 + + strategy: + matrix: + php: ['8.0'] + + steps: + - name: Checkout Code + uses: actions/checkout@v2 + + - name: Setup PHP + uses: shivammathur/setup-php@v2 + with: + php-version: ${{ matrix.php }} + tools: composer:v2 + coverage: xdebug + + - name: Setup Problem Matchers + run: echo "::add-matcher::${{ runner.tool_cache }}/phpunit.json" + + - name: Install Dependencies + uses: nick-invision/retry@v1 + with: + timeout_minutes: 5 + max_attempts: 5 + command: composer update --no-interaction --no-progress + + - name: Execute PHPUnit + run: vendor/bin/phpunit --coverage-text --testsuite="Mockery Test Suite PHP8" + + php81: + name: PHP ${{ matrix.php }} + runs-on: ubuntu-20.04 + + strategy: + matrix: + php: ['8.1'] + + steps: + - name: Checkout Code + uses: actions/checkout@v2 + + - name: Setup PHP + uses: shivammathur/setup-php@v2 + with: + php-version: ${{ matrix.php }} + tools: composer:v2 + coverage: none + + - name: Setup Problem Matchers + run: echo "::add-matcher::${{ runner.tool_cache }}/phpunit.json" + + - name: Mimic PHP 8.0 + run: composer config platform.php 8.0.999 + + - name: Install Dependencies + uses: nick-invision/retry@v1 + with: + timeout_minutes: 5 + max_attempts: 5 + command: composer update --no-interaction --no-progress + + - name: Execute PHPUnit + run: vendor/bin/phpunit --testsuite="Mockery Test Suite PHP8" diff --git a/.scrutinizer.yml b/.scrutinizer.yml deleted file mode 100644 index 29347813f..000000000 --- a/.scrutinizer.yml +++ /dev/null @@ -1,24 +0,0 @@ -filter: - paths: [library/*] - excluded_paths: [vendor/*, tests/*, examples/*] -before_commands: - - 'composer install --prefer-source' -tools: - external_code_coverage: - timeout: 300 - php_code_sniffer: true - php_cpd: - enabled: true - excluded_dirs: [vendor, tests, examples] - php_pdepend: - enabled: true - excluded_dirs: [vendor, tests, examples] - php_loc: - enabled: true - excluded_dirs: [vendor, tests, examples] - php_hhvm: false - php_mess_detector: true - php_analyzer: true -changetracking: - bug_patterns: ["\bfix(?:es|ed)?\b"] - feature_patterns: ["\badd(?:s|ed)?\b", "\bimplement(?:s|ed)?\b"] diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index 361e19e6a..000000000 --- a/.travis.yml +++ /dev/null @@ -1,60 +0,0 @@ -language: php - -matrix: - include: - - php: 5.6 - - php: 7.0 - - php: 7.1 - - php: 7.2 - - php: 7.3 - - php: 7.4 - - php: 8.0 - -before_install: - # Install extensions for PHP 5.x series. 7.x includes them by default. - - | - composer self-update --2 - if [[ $TRAVIS_PHP_VERSION == 5.6 ]]; then - cat <<< ' - extension=mongo.so - extension=redis.so - ' >> ~/.phpenv/versions/"$(phpenv version-name)"/etc/conf.d/travis.ini - fi - -install: - - travis_retry composer update --no-interaction - -script: -- | - if [[ $TRAVIS_PHP_VERSION == 5.6 ]]; then - ./vendor/bin/phpunit --coverage-text --coverage-clover="build/logs/clover.xml" --testsuite="Mockery Test Suite PHP5"; - elif [[ $TRAVIS_PHP_VERSION == '8.0' ]]; then - ./vendor/bin/phpunit --coverage-text --coverage-clover="build/logs/clover.xml" --testsuite="Mockery Test Suite PHP8"; - else - ./vendor/bin/phpunit --coverage-text --coverage-clover="build/logs/clover.xml" --testsuite="Mockery Test Suite PHP7"; - fi - -after_success: - - composer require satooshi/php-coveralls - - vendor/bin/coveralls -v - - wget https://scrutinizer-ci.com/ocular.phar - - php ocular.phar code-coverage:upload --format=php-clover "build/logs/clover.xml" - - make apidocs - -notifications: - email: - - padraic.brady@gmail.com - - dave@atstsolutions.co.uk - - irc: irc.freenode.org#mockery -deploy: - overwrite: true - provider: pages - file_glob: true - file: docs/api/* - local_dir: docs/api - skip_cleanup: true - github_token: $GITHUB_TOKEN - on: - branch: master - php: '7.1' diff --git a/README.md b/README.md index 803f845fc..491742d69 100644 --- a/README.md +++ b/README.md @@ -1,9 +1,8 @@ Mockery ======= -[![Build Status](https://travis-ci.org/mockery/mockery.svg?branch=master)](https://travis-ci.org/mockery/mockery) +[![Build Status](https://github.com/mockery/mockery/workflows/tests/badge.svg)](https://github.com/mockery/mockery/actions) [![Latest Stable Version](https://poser.pugx.org/mockery/mockery/v/stable.svg)](https://packagist.org/packages/mockery/mockery) -[![Coverage Status](https://coveralls.io/repos/github/mockery/mockery/badge.svg)](https://coveralls.io/github/mockery/mockery) [![Total Downloads](https://poser.pugx.org/mockery/mockery/downloads.svg)](https://packagist.org/packages/mockery/mockery) Mockery is a simple yet flexible PHP mock object framework for use in unit testing diff --git a/library/Mockery/Generator/StringManipulation/Pass/RemoveUnserializeForInternalSerializableClassesPass.php b/library/Mockery/Generator/StringManipulation/Pass/RemoveUnserializeForInternalSerializableClassesPass.php index 840fe9986..0abefe265 100644 --- a/library/Mockery/Generator/StringManipulation/Pass/RemoveUnserializeForInternalSerializableClassesPass.php +++ b/library/Mockery/Generator/StringManipulation/Pass/RemoveUnserializeForInternalSerializableClassesPass.php @@ -30,7 +30,8 @@ */ class RemoveUnserializeForInternalSerializableClassesPass { - const DUMMY_METHOD_DEFINITION = 'public function unserialize($string) {} '; + const DUMMY_METHOD_DEFINITION_LEGACY = 'public function unserialize($string) {} '; + const DUMMY_METHOD_DEFINITION = 'public function unserialize(string $data): void {} '; public function apply($code, MockConfiguration $config) { @@ -44,7 +45,7 @@ public function apply($code, MockConfiguration $config) return $code; } - $code = $this->appendToClass($code, self::DUMMY_METHOD_DEFINITION); + $code = $this->appendToClass($code, \PHP_VERSION_ID < 80100 ? self::DUMMY_METHOD_DEFINITION_LEGACY : self::DUMMY_METHOD_DEFINITION); return $code; } diff --git a/phpunit.xml.dist b/phpunit.xml.dist index ba4fa85c1..904dac005 100644 --- a/phpunit.xml.dist +++ b/phpunit.xml.dist @@ -6,24 +6,26 @@ ./tests - ./tests/PHP80 + ./tests/PHP80 + ./tests/PHP81 ./tests - ./tests/PHP70 - ./tests/PHP71 - ./tests/PHP72 + ./tests/PHP70 + ./tests/PHP71 + ./tests/PHP72 ./tests/PHP80 + ./tests/PHP81 ./tests - ./tests/PHP56 ./tests/PHP70 ./tests/PHP71 ./tests/PHP72 ./tests/PHP80 + ./tests/PHP81 diff --git a/tests/Mockery/ContainerTest.php b/tests/Mockery/ContainerTest.php index fd51609d1..728640de2 100644 --- a/tests/Mockery/ContainerTest.php +++ b/tests/Mockery/ContainerTest.php @@ -1090,6 +1090,9 @@ public function testInterfacesCanHaveAssertions() $m->foo(); } + /** + * @requires PHP < 8.0 + */ public function testMockingIteratorAggregateDoesNotImplementIterator() { $mock = mock('MockeryTest_ImplementsIteratorAggregate'); @@ -1128,6 +1131,9 @@ public function testMockingIteratorDoesNotImplementIteratorAlongside() $this->assertInstanceOf('Traversable', $mock); } + /** + * @requires PHP < 8.0 + */ public function testMockingIteratorDoesNotImplementIterator() { $mock = mock('MockeryTest_ImplementsIterator'); @@ -1732,18 +1738,16 @@ class MockeryTest_TestInheritedType { } -if (PHP_VERSION_ID >= 50400) { - class MockeryTest_MockCallableTypeHint +class MockeryTest_MockCallableTypeHint +{ + public function foo(callable $baz) { - public function foo(callable $baz) - { - $baz(); - } + $baz(); + } - public function bar(callable $callback = null) - { - $callback(); - } + public function bar(callable $callback = null) + { + $callback(); } } @@ -1754,34 +1758,36 @@ public function __toString() } } -class MockeryTest_ImplementsIteratorAggregate implements IteratorAggregate -{ - public function getIterator() +if (\PHP_VERSION_ID < 80000) { + class MockeryTest_ImplementsIteratorAggregate implements IteratorAggregate { - return new ArrayIterator(array()); + public function getIterator() + { + return new ArrayIterator(array()); + } } -} -class MockeryTest_ImplementsIterator implements Iterator -{ - public function rewind() + class MockeryTest_ImplementsIterator implements Iterator { - } + public function rewind() + { + } - public function current() - { - } + public function current() + { + } - public function key() - { - } + public function key() + { + } - public function next() - { - } + public function next() + { + } - public function valid() - { + public function valid() + { + } } } diff --git a/tests/PHP80/Php80LanguageFeaturesTest.php b/tests/PHP80/Php80LanguageFeaturesTest.php index 2c6d8de6b..bc875e12b 100644 --- a/tests/PHP80/Php80LanguageFeaturesTest.php +++ b/tests/PHP80/Php80LanguageFeaturesTest.php @@ -2,7 +2,10 @@ namespace test\Mockery; +use ArrayIterator; use DateTime; +use Iterator; +use IteratorAggregate; use Mockery\Adapter\Phpunit\MockeryTestCase; use ReturnTypeWillChange; @@ -11,6 +14,21 @@ */ class Php80LanguageFeaturesTest extends MockeryTestCase { + public function testMockingIteratorAggregateDoesNotImplementIterator() + { + $mock = mock('test\Mockery\ImplementsIteratorAggregate'); + $this->assertInstanceOf('IteratorAggregate', $mock); + $this->assertInstanceOf('Traversable', $mock); + $this->assertNotInstanceOf('Iterator', $mock); + } + + public function testMockingIteratorDoesNotImplementIterator() + { + $mock = mock('test\Mockery\ImplementsIterator'); + $this->assertInstanceOf('Iterator', $mock); + $this->assertInstanceOf('Traversable', $mock); + } + /** @test */ public function it_can_mock_a_class_with_a_mixed_argument_type_hint() { @@ -73,32 +91,36 @@ public function it_can_mock_a_class_with_a_parent_return_type_hint() $this->assertInstanceOf(\stdClass::class, $mock->foo()); } +} - /** - * @test - * @requires PHP 8.1 - */ - public function it_can_mock_an_internal_class_with_tentative_return_types() +class ImplementsIteratorAggregate implements IteratorAggregate +{ + public function getIterator(): ArrayIterator { - $mock = spy(DateTime::class); + return new ArrayIterator([]); + } +} - $this->assertSame(0, $mock->getTimestamp()); +class ImplementsIterator implements Iterator +{ + public function rewind(): void + { } - /** @test */ - public function it_can_mock_a_class_with_return_type_will_change_attribute_and_no_return_type() + public function current(): mixed { - $mock = spy(ReturnTypeWillChangeAttributeNoReturnType::class); + } - $this->assertNull($mock->getTimestamp()); + public function key(): mixed + { } - /** @test */ - public function it_can_mock_a_class_with_return_type_will_change_attribute_and_wrong_return_type() + public function next(): void { - $mock = spy(ReturnTypeWillChangeAttributeWrongReturnType::class); + } - $this->assertSame(0.0, $mock->getTimestamp()); + public function valid(): bool + { } } @@ -150,19 +172,3 @@ public function foo(): parent { } } - -class ReturnTypeWillChangeAttributeNoReturnType extends DateTime -{ - #[ReturnTypeWillChange] - public function getTimestamp() - { - } -} - -class ReturnTypeWillChangeAttributeWrongReturnType extends DateTime -{ - #[ReturnTypeWillChange] - public function getTimestamp(): float - { - } -} diff --git a/tests/PHP81/Php81LanguageFeaturesTest.php b/tests/PHP81/Php81LanguageFeaturesTest.php new file mode 100644 index 000000000..1bdfb39de --- /dev/null +++ b/tests/PHP81/Php81LanguageFeaturesTest.php @@ -0,0 +1,83 @@ +assertInstanceOf("Serializable", $mock); + } + + /** @test */ + public function it_can_mock_an_internal_class_with_tentative_return_types() + { + $mock = spy(DateTime::class); + + $this->assertSame(0, $mock->getTimestamp()); + } + + /** @test */ + public function it_can_mock_a_class_with_return_type_will_change_attribute_and_no_return_type() + { + $mock = spy(ReturnTypeWillChangeAttributeNoReturnType::class); + + $this->assertNull($mock->getTimestamp()); + } + + /** @test */ + public function it_can_mock_a_class_with_return_type_will_change_attribute_and_wrong_return_type() + { + $mock = spy(ReturnTypeWillChangeAttributeWrongReturnType::class); + + $this->assertSame(0.0, $mock->getTimestamp()); + } +} + +class ClassThatImplementsSerializable implements Serializable +{ + public function serialize(): ?string + { + } + + public function __serialize(): array + { + } + + public function unserialize(string $data): void + { + } + + public function __unserialize(array $data): void + { + } +} + +class ReturnTypeWillChangeAttributeNoReturnType extends DateTime +{ + #[ReturnTypeWillChange] + public function getTimestamp() + { + } +} + +class ReturnTypeWillChangeAttributeWrongReturnType extends DateTime +{ + #[ReturnTypeWillChange] + public function getTimestamp(): float + { + } +} From 2bbc2b130b37f23098b440911785bf0f6792909b Mon Sep 17 00:00:00 2001 From: Graham Campbell Date: Sun, 22 Aug 2021 19:54:39 +0100 Subject: [PATCH 2/2] Update .gitattributes --- .gitattributes | 1 - 1 file changed, 1 deletion(-) diff --git a/.gitattributes b/.gitattributes index 3fbfecd6e..8b3a59f0a 100644 --- a/.gitattributes +++ b/.gitattributes @@ -6,7 +6,6 @@ .gitattributes export-ignore .gitignore export-ignore .php_cs export-ignore -.scrutinizer.yml export-ignore .styleci.yml export-ignore Makefile export-ignore phpunit.xml.dist export-ignore