diff --git a/.gitattributes b/.gitattributes index 2ee8814..d3f5826 100644 --- a/.gitattributes +++ b/.gitattributes @@ -1,11 +1,13 @@ -.gitattributes export-ignore -.github/ export-ignore -.gitignore export-ignore -.readthedocs.yml export-ignore -.travis.yml export-ignore -docs/ export-ignore -phpbench.json export-ignore -phpcs.xml.dist export-ignore -phpunit.xml.dist export-ignore -resources/ export-ignore -tests/ export-ignore +/.gitattributes export-ignore +/.github/ export-ignore +/.gitignore export-ignore +/.readthedocs.yml export-ignore +/codecov.yml export-ignore +/docs/ export-ignore +/phpbench.json export-ignore +/phpcs.xml.dist export-ignore +/phpunit.xml.dist export-ignore +/resources/ export-ignore +/SECURITY.md export-ignore +/SECURITY.md.sig export-ignore +/tests/ export-ignore diff --git a/.github/workflows/continuous-integration.yml b/.github/workflows/continuous-integration.yml new file mode 100644 index 0000000..8c14d39 --- /dev/null +++ b/.github/workflows/continuous-integration.yml @@ -0,0 +1,110 @@ +# https://help.github.com/en/categories/automating-your-workflow-with-github-actions + +name: "CI" + +on: + pull_request: + push: + branches: + - "master" + +env: + COMPOSER_ROOT_VERSION: "1.99.99" + +jobs: + + coding-standards: + name: "Coding Standards" + runs-on: "ubuntu-latest" + steps: + - uses: "actions/checkout@v2" + - uses: "shivammathur/setup-php@v2" + with: + php-version: "7.4" + coverage: "none" + ini-values: "memory_limit=-1" + - uses: "ramsey/composer-install@v1" + - name: "Run the linter" + run: "composer lint -- --colors" + - name: "Check coding standards" + run: "./vendor/bin/phpcs --colors" + + static-analysis: + name: "Static Analysis" + runs-on: "ubuntu-latest" + steps: + - uses: "actions/checkout@v2" + - uses: "shivammathur/setup-php@v2" + with: + php-version: "7.4" + coverage: "none" + ini-values: "memory_limit=-1" + - uses: "ramsey/composer-install@v1" + - name: "Run PHPStan" + run: "composer phpstan -- --ansi" + - name: "Run Psalm" + run: "composer psalm -- --shepherd" + + benchmark: + name: "Benchmark" + runs-on: "ubuntu-latest" + continue-on-error: ${{ matrix.experimental }} + strategy: + fail-fast: false + matrix: + php-version: + - "7.2" + - "7.3" + - "7.4" + experimental: + - false + include: + - php-version: "8.0" + experimental: true + composer-options: "--ignore-platform-reqs" + steps: + - uses: "actions/checkout@v2" + - uses: "shivammathur/setup-php@v2" + with: + php-version: "${{ matrix.php-version }}" + extensions: bcmath, ctype, gmp + coverage: "none" + ini-values: "memory_limit=-1" + - uses: "ramsey/composer-install@v1" + with: + composer-options: "${{ matrix.composer-options }}" + - name: "Run PHPBench" + run: "composer phpbench -- --ansi" + + unit-tests: + name: "Unit Tests" + runs-on: "ubuntu-latest" + continue-on-error: ${{ matrix.experimental }} + strategy: + fail-fast: false + matrix: + php-version: + - "7.2" + - "7.3" + - "7.4" + experimental: + - false + include: + - php-version: "8.0" + experimental: true + composer-options: "--ignore-platform-reqs" + steps: + - uses: "actions/checkout@v2" + - uses: "shivammathur/setup-php@v2" + with: + php-version: "${{ matrix.php-version }}" + extensions: bcmath, ctype, gmp + coverage: "pcov" + ini-values: "memory_limit=-1" + - uses: "ramsey/composer-install@v1" + with: + composer-options: "${{ matrix.composer-options }}" + - name: "Run unit tests" + run: "./vendor/bin/phpunit --verbose --colors=always --coverage-clover build/logs/clover.xml --coverage-text" + - name: "Publish coverage report to Codecov" + uses: "codecov/codecov-action@v1" diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index 5aa0eca..0000000 --- a/.travis.yml +++ /dev/null @@ -1,69 +0,0 @@ -language: php -os: linux -cache: - directories: - - /home/travis/.composer/cache/ - -services: - - docker - -jobs: - fast_finish: true - include: - - php: 7.2 - - php: 7.2 - arch: s390x - - php: 7.2 - arch: arm64 - env: ARCH=arm32 - - php: 7.3 - - php: 7.3 - arch: s390x - - php: 7.3 - arch: arm64 - env: ARCH=arm32 - - php: 7.4 - - php: 7.4 - arch: s390x - - php: 7.4 - arch: arm64 - env: ARCH=arm32 - - php: nightly - env: COMPOSER_OPTIONS=--ignore-platform-reqs - - php: nightly - arch: s390x - env: COMPOSER_OPTIONS=--ignore-platform-reqs - allow_failures: - - php: nightly - -addons: - apt: - update: true - packages: - - bsdmainutils - - libsodium-dev - - uuid-dev - -before_install: - - travis_retry ./resources/scripts/travis-before-install.sh - - ./resources/scripts/cmd-proxy.sh ./resources/scripts/system-info.sh - - if [ "${TRAVIS_EVENT_TYPE}" != "cron" ]; then phpenv config-rm xdebug.ini || echo 'No xdebug config.'; fi - -install: - - travis_retry ./resources/scripts/cmd-proxy.sh composer require --no-update "php-coveralls/php-coveralls:^1 | ^2" - - travis_retry ./resources/scripts/cmd-proxy.sh composer install --no-interaction --prefer-dist --no-progress --no-suggest $COMPOSER_OPTIONS - -before_script: - - mkdir -p build/cache - - mkdir -p build/logs - -script: - - ./resources/scripts/cmd-proxy.sh composer lint - - ./resources/scripts/cmd-proxy.sh composer phpcs - - ./resources/scripts/cmd-proxy.sh composer phpstan - - ./resources/scripts/cmd-proxy.sh composer psalm - - ./resources/scripts/cmd-proxy.sh composer phpbench - - travis_wait 30 ./resources/scripts/cmd-proxy.sh ./vendor/bin/phpunit --verbose --coverage-clover build/logs/clover.xml - -after_success: - - travis_retry ./resources/scripts/php-coveralls.sh diff --git a/README.md b/README.md index 0e539e6..75a3224 100644 --- a/README.md +++ b/README.md @@ -1,12 +1,20 @@ -# ramsey/uuid +

ramsey/uuid

-[![Source Code][badge-source]][source] -[![Latest Version][badge-release]][release] -[![Software License][badge-license]][license] -[![PHP Version][badge-php]][php] -[![Build Status][badge-build]][build] -[![Coverage Status][badge-coverage]][coverage] -[![Total Downloads][badge-downloads]][downloads] +

+ A PHP library for generating and working with UUIDs. +

+ +

+ Source Code + Download Package + PHP Programming Language + Build Status + Codecov Code Coverage + Psalm Type Coverage + Read License + Package downloads on Packagist + Chat with the maintainers +

ramsey/uuid is a PHP library for generating and working with universally unique identifiers (UUIDs). @@ -61,19 +69,3 @@ information. [pyuuid]: http://docs.python.org/3/library/uuid.html [composer]: http://getcomposer.org/ [contributing.md]: https://github.com/ramsey/uuid/blob/master/.github/CONTRIBUTING.md - -[badge-source]: https://img.shields.io/badge/source-ramsey/uuid-blue.svg?style=flat-square -[badge-release]: https://img.shields.io/packagist/v/ramsey/uuid.svg?style=flat-square&label=release -[badge-license]: https://img.shields.io/packagist/l/ramsey/uuid.svg?style=flat-square -[badge-php]: https://img.shields.io/packagist/php-v/ramsey/uuid.svg?style=flat-square -[badge-build]: https://img.shields.io/travis/ramsey/uuid/master.svg?style=flat-square -[badge-coverage]: https://img.shields.io/coveralls/github/ramsey/uuid/master.svg?style=flat-square -[badge-downloads]: https://img.shields.io/packagist/dt/ramsey/uuid.svg?style=flat-square&colorB=mediumvioletred - -[source]: https://github.com/ramsey/uuid -[release]: https://packagist.org/packages/ramsey/uuid -[license]: https://github.com/ramsey/uuid/blob/master/LICENSE -[php]: https://php.net -[build]: https://travis-ci.org/ramsey/uuid -[coverage]: https://coveralls.io/github/ramsey/uuid?branch=master -[downloads]: https://packagist.org/packages/ramsey/uuid diff --git a/SECURITY.md b/SECURITY.md new file mode 100644 index 0000000..8325fe4 --- /dev/null +++ b/SECURITY.md @@ -0,0 +1,95 @@ +# Security Policy + +I, Ben Ramsey, take the security of my software products and services seriously, which includes all source code repositories managed through my GitHub account, [@ramsey](https://github.com/ramsey). + +If you believe you have found a security vulnerability in any repository I own, please report it to me as described below. + +## Reporting Security Issues + +**Please do not report security vulnerabilities through public GitHub issues.** + +Instead, please report them to me via . If possible, encrypt your message with my PGP encryption key, provided below. + +You should receive a response within 14 days. If for some reason you do not, please follow up via email to ensure I received your original message. + +Please include the requested information listed below (as much as you can provide) to help me better understand the nature and scope of the possible issue: + + * Product version containing the issue + * Type of issue (e.g. buffer overflow, SQL injection, cross-site scripting, etc.) + * Full paths of source file(s) related to the manifestation of the issue + * The location of the affected source code (tag/branch/commit or direct URL) + * Any special configuration required to reproduce the issue + * Step-by-step instructions to reproduce the issue + * Proof-of-concept or exploit code (if possible) + * Impact of the issue, including how an attacker might exploit the issue + +This information will help me triage your report more quickly. + +## Preferred Languages + +I prefer all communications in English. + +## Policy + +I follow the [Coordinated Vulnerability Disclosure](https://vuls.cert.org/confluence/display/CVD/The+CERT+Guide+to+Coordinated+Vulnerability+Disclosure) process. + +## Encryption Key for `security@ramsey.dev` + +For increased privacy when reporting sensitive issues, you may encrypt your message using the key below: + +``` +-----BEGIN PGP PUBLIC KEY BLOCK----- + +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 +nmgawbBHA02D5xEqB5SU3WJu +=eJNx +-----END PGP PUBLIC KEY BLOCK----- +``` diff --git a/SECURITY.md.sig b/SECURITY.md.sig new file mode 100644 index 0000000..fef8999 Binary files /dev/null and b/SECURITY.md.sig differ diff --git a/codecov.yml b/codecov.yml new file mode 100644 index 0000000..a35f023 --- /dev/null +++ b/codecov.yml @@ -0,0 +1,29 @@ +codecov: + require_ci_to_pass: yes + +coverage: + precision: 2 + round: down + range: "70...100" + status: + project: + default: + target: auto + threshold: 0% + patch: + default: + target: auto + threshold: 0% + +parsers: + gcov: + branch_detection: + conditional: yes + loop: yes + method: no + macro: no + +comment: + layout: "reach,diff,flags,tree" + behavior: default + require_changes: false diff --git a/composer.json b/composer.json index 41d500b..b308471 100644 --- a/composer.json +++ b/composer.json @@ -17,27 +17,27 @@ "symfony/polyfill-ctype": "^1.8" }, "require-dev": { - "codeception/aspect-mock": "^3", - "dealerdirect/phpcodesniffer-composer-installer": "^0.6.2 || ^0.7.0", + "dealerdirect/phpcodesniffer-composer-installer": "^0.7.0", "doctrine/annotations": "^1.8", - "goaop/framework": "^2", "mockery/mockery": "^1.3", "moontoast/math": "^1.1", "paragonie/random-lib": "^2", + "php-mock/php-mock": "^2.2", "php-mock/php-mock-mockery": "^1.3", - "php-mock/php-mock-phpunit": "^2.5", "php-parallel-lint/php-parallel-lint": "^1.1", - "phpbench/phpbench": "^0.17.1", + "phpbench/phpbench": "1.0.0-alpha2", "phpstan/extension-installer": "^1.0", "phpstan/phpstan": "^0.12", "phpstan/phpstan-mockery": "^0.12", "phpstan/phpstan-phpunit": "^0.12", - "phpunit/phpunit": "^8.5", + "phpunit/phpunit": "^8.5 || ^9", "psy/psysh": "^0.10.0", "slevomat/coding-standard": "^6.0", "squizlabs/php_codesniffer": "^3.5", - "vimeo/psalm": "3.9.4" + "vimeo/psalm": "^3.18" }, + "minimum-stability": "dev", + "prefer-stable": true, "suggest": { "ext-bcmath": "Enables faster math with arbitrary-precision integers using BCMath.", "ext-ctype": "Enables faster processing of character classification using ctype functions.", diff --git a/src/Converter/Number/GenericNumberConverter.php b/src/Converter/Number/GenericNumberConverter.php index c85bc3a..b95d5e0 100644 --- a/src/Converter/Number/GenericNumberConverter.php +++ b/src/Converter/Number/GenericNumberConverter.php @@ -19,7 +19,7 @@ use Ramsey\Uuid\Math\CalculatorInterface; use Ramsey\Uuid\Type\Integer as IntegerObject; /** - * GenericNumberConverter uses the provided calculate to convert decimal + * GenericNumberConverter uses the provided calculator to convert decimal * numbers to and from hexadecimal values * * @psalm-immutable diff --git a/src/Generator/DceSecurityGenerator.php b/src/Generator/DceSecurityGenerator.php index a3f07f2..79f0566 100644 --- a/src/Generator/DceSecurityGenerator.php +++ b/src/Generator/DceSecurityGenerator.php @@ -137,8 +137,8 @@ class DceSecurityGenerator implements DceSecurityGeneratorInterface ); } - $domainByte = pack('n', $localDomain)[1]; - $identifierBytes = hex2bin(str_pad($identifierHex, 8, '0', STR_PAD_LEFT)); + $domainByte = (string) pack('n', $localDomain)[1]; + $identifierBytes = (string) hex2bin(str_pad($identifierHex, 8, '0', STR_PAD_LEFT)); if ($node instanceof Hexadecimal) { $node = $node->toString(); diff --git a/src/Generator/DefaultNameGenerator.php b/src/Generator/DefaultNameGenerator.php index 270e8fb..1c0b004 100644 --- a/src/Generator/DefaultNameGenerator.php +++ b/src/Generator/DefaultNameGenerator.php @@ -28,8 +28,12 @@ class DefaultNameGenerator implements NameGeneratorInterface /** @psalm-pure */ public function generate(UuidInterface $ns, string $name, string $hashAlgorithm): string { - /** @var string|bool $bytes */ - $bytes = @hash($hashAlgorithm, $ns->getBytes() . $name, true); + try { + /** @var string|bool $bytes */ + $bytes = @hash($hashAlgorithm, $ns->getBytes() . $name, true); + } catch (\ValueError $e) { + $bytes = false; // keep same behavior than PHP 7 + } if ($bytes === false) { throw new NameException(sprintf( diff --git a/src/Guid/Fields.php b/src/Guid/Fields.php index 49db4ed..d8a1a2b 100644 --- a/src/Guid/Fields.php +++ b/src/Guid/Fields.php @@ -94,6 +94,7 @@ final class Fields implements FieldsInterface public function getTimeLow(): Hexadecimal { // Swap the bytes from little endian to network byte order. + /** @var array $hex */ $hex = unpack( 'H*', pack( @@ -109,6 +110,7 @@ final class Fields implements FieldsInterface public function getTimeMid(): Hexadecimal { // Swap the bytes from little endian to network byte order. + /** @var array $hex */ $hex = unpack( 'H*', pack( @@ -123,6 +125,7 @@ final class Fields implements FieldsInterface public function getTimeHiAndVersion(): Hexadecimal { // Swap the bytes from little endian to network byte order. + /** @var array $hex */ $hex = unpack( 'H*', pack( @@ -172,6 +175,7 @@ final class Fields implements FieldsInterface return null; } + /** @var array $parts */ $parts = unpack('n*', $this->bytes); return ((int) $parts[4] >> 4) & 0x00f; diff --git a/src/Provider/Dce/SystemDceSecurityProvider.php b/src/Provider/Dce/SystemDceSecurityProvider.php index 1a1f4cf..67b58eb 100644 --- a/src/Provider/Dce/SystemDceSecurityProvider.php +++ b/src/Provider/Dce/SystemDceSecurityProvider.php @@ -178,7 +178,7 @@ class SystemDceSecurityProvider implements DceSecurityProviderInterface } /** @var string $sid */ - $sid = str_getcsv(trim($response))[1] ?? ''; + $sid = str_getcsv(trim((string) $response))[1] ?? ''; if (($lastHyphen = strrpos($sid, '-')) === false) { return ''; @@ -207,7 +207,7 @@ class SystemDceSecurityProvider implements DceSecurityProviderInterface } /** @var string[] $userGroups */ - $userGroups = preg_split('/\s{2,}/', $response, -1, PREG_SPLIT_NO_EMPTY); + $userGroups = preg_split('/\s{2,}/', (string) $response, -1, PREG_SPLIT_NO_EMPTY); $firstGroup = trim($userGroups[1] ?? '', "* \t\n\r\0\x0B"); @@ -222,7 +222,7 @@ class SystemDceSecurityProvider implements DceSecurityProviderInterface } /** @var string[] $userGroup */ - $userGroup = preg_split('/\s{2,}/', $response, -1, PREG_SPLIT_NO_EMPTY); + $userGroup = preg_split('/\s{2,}/', (string) $response, -1, PREG_SPLIT_NO_EMPTY); $sid = $userGroup[1] ?? ''; diff --git a/src/Rfc4122/Fields.php b/src/Rfc4122/Fields.php index 0989d84..2ccc20b 100644 --- a/src/Rfc4122/Fields.php +++ b/src/Rfc4122/Fields.php @@ -177,6 +177,7 @@ final class Fields implements FieldsInterface return null; } + /** @var array $parts */ $parts = unpack('n*', $this->bytes); return (int) $parts[4] >> 12; diff --git a/src/Rfc4122/VariantTrait.php b/src/Rfc4122/VariantTrait.php index c32a8ce..4c98165 100644 --- a/src/Rfc4122/VariantTrait.php +++ b/src/Rfc4122/VariantTrait.php @@ -58,6 +58,7 @@ trait VariantTrait throw new InvalidBytesException('Invalid number of bytes'); } + /** @var array $parts */ $parts = unpack('n*', $this->getBytes()); // $parts[5] is a 16-bit, unsigned integer containing the variant bits diff --git a/src/Type/Integer.php b/src/Type/Integer.php index 05d420a..540ecbe 100644 --- a/src/Type/Integer.php +++ b/src/Type/Integer.php @@ -36,7 +36,7 @@ use function substr; final class Integer implements NumberInterface { /** - * @var string + * @psalm-var numeric-string */ private $value; @@ -80,7 +80,10 @@ final class Integer implements NumberInterface $this->isNegative = true; } - $this->value = $value; + /** @psalm-var numeric-string $numericValue */ + $numericValue = $value; + + $this->value = $numericValue; } public function isNegative(): bool @@ -88,6 +91,9 @@ final class Integer implements NumberInterface return $this->isNegative; } + /** + * @psalm-return numeric-string + */ public function toString(): string { return $this->value; diff --git a/src/UuidFactory.php b/src/UuidFactory.php index feddef8..6f2cea0 100644 --- a/src/UuidFactory.php +++ b/src/UuidFactory.php @@ -471,10 +471,14 @@ class UuidFactory implements UuidFactoryInterface */ private function uuidFromBytesAndVersion(string $bytes, int $version): UuidInterface { - $timeHi = (int) unpack('n*', substr($bytes, 6, 2))[1]; + /** @var array $unpackedTime */ + $unpackedTime = unpack('n*', substr($bytes, 6, 2)); + $timeHi = (int) $unpackedTime[1]; $timeHiAndVersion = pack('n*', BinaryUtils::applyVersion($timeHi, $version)); - $clockSeqHi = (int) unpack('n*', substr($bytes, 8, 2))[1]; + /** @var array $unpackedClockSeq */ + $unpackedClockSeq = unpack('n*', substr($bytes, 8, 2)); + $clockSeqHi = (int) $unpackedClockSeq[1]; $clockSeqHiAndReserved = pack('n*', BinaryUtils::applyVariant($clockSeqHi)); $bytes = substr_replace($bytes, $timeHiAndVersion, 6, 2); diff --git a/tests/Generator/CombGeneratorTest.php b/tests/Generator/CombGeneratorTest.php index 6649b49..dd43d4a 100644 --- a/tests/Generator/CombGeneratorTest.php +++ b/tests/Generator/CombGeneratorTest.php @@ -5,7 +5,6 @@ declare(strict_types=1); namespace Ramsey\Uuid\Test\Generator; use Exception; -use PHPUnit\Framework\Error\Error as PHPUnitError; use PHPUnit\Framework\MockObject\MockObject; use Ramsey\Uuid\Converter\NumberConverterInterface; use Ramsey\Uuid\Exception\InvalidArgumentException; @@ -127,7 +126,7 @@ class CombGeneratorTest extends TestCase $generator = new CombGenerator($randomGenerator, $converter); - $this->expectException(PHPUnitError::class); + $this->expectError(); $generator->generate(7); } } diff --git a/tests/Generator/DefaultTimeGeneratorTest.php b/tests/Generator/DefaultTimeGeneratorTest.php index acf98bd..f12a93d 100644 --- a/tests/Generator/DefaultTimeGeneratorTest.php +++ b/tests/Generator/DefaultTimeGeneratorTest.php @@ -4,7 +4,6 @@ declare(strict_types=1); namespace Ramsey\Uuid\Test\Generator; -use AspectMock\Test as AspectMock; use Exception; use Mockery; use Mockery\MockInterface; @@ -21,6 +20,7 @@ use Ramsey\Uuid\Provider\TimeProviderInterface; use Ramsey\Uuid\Test\TestCase; use Ramsey\Uuid\Type\Hexadecimal; use Ramsey\Uuid\Type\Time; +use phpmock\mockery\PHPMockery; use function hex2bin; @@ -80,7 +80,6 @@ class DefaultTimeGeneratorTest extends TestCase parent::tearDown(); unset($this->timeProvider, $this->nodeProvider, $this->timeConverter); Mockery::close(); - AspectMock::clean(); } public function testGenerateUsesNodeProviderWhenNodeIsNull(): void @@ -159,7 +158,10 @@ class DefaultTimeGeneratorTest extends TestCase */ public function testGenerateUsesRandomSequenceWhenClockSeqNull(): void { - $randomInt = AspectMock::func('Ramsey\Uuid\Generator', 'random_int', 9622); + PHPMockery::mock('Ramsey\Uuid\Generator', 'random_int') + ->once() + ->with(0, 0x3fff) + ->andReturn(9622); $this->timeConverter->expects($this->once()) ->method('calculateTime') ->with($this->currentTime['sec'], $this->currentTime['usec']) @@ -170,7 +172,6 @@ class DefaultTimeGeneratorTest extends TestCase $this->timeProvider ); $defaultTimeGenerator->generate($this->nodeId); - $randomInt->verifyInvokedOnce([0, 0x3fff]); } /** @@ -179,9 +180,9 @@ class DefaultTimeGeneratorTest extends TestCase */ public function testGenerateThrowsExceptionWhenExceptionThrownByRandomint(): void { - AspectMock::func('Ramsey\Uuid\Generator', 'random_int', function (): void { - throw new Exception('Could not gather sufficient random data'); - }); + PHPMockery::mock('Ramsey\Uuid\Generator', 'random_int') + ->once() + ->andThrow(new Exception('Could not gather sufficient random data')); $defaultTimeGenerator = new DefaultTimeGenerator( $this->nodeProvider, diff --git a/tests/Generator/PeclUuidNameGeneratorTest.php b/tests/Generator/PeclUuidNameGeneratorTest.php index 65b9cb3..1c946bb 100644 --- a/tests/Generator/PeclUuidNameGeneratorTest.php +++ b/tests/Generator/PeclUuidNameGeneratorTest.php @@ -29,10 +29,14 @@ class PeclUuidNameGeneratorTest extends TestCase // Need to add the version and variant, since ext-uuid already includes // these in the values returned. - $timeHi = (int) unpack('n*', substr($expectedBytes, 6, 2))[1]; + /** @var array $unpackedTime */ + $unpackedTime = unpack('n*', substr($expectedBytes, 6, 2)); + $timeHi = (int) $unpackedTime[1]; $timeHiAndVersion = pack('n*', BinaryUtils::applyVersion($timeHi, $version)); - $clockSeqHi = (int) unpack('n*', substr($expectedBytes, 8, 2))[1]; + /** @var array $unpackedClockSeq */ + $unpackedClockSeq = unpack('n*', substr($expectedBytes, 8, 2)); + $clockSeqHi = (int) $unpackedClockSeq[1]; $clockSeqHiAndReserved = pack('n*', BinaryUtils::applyVariant($clockSeqHi)); $expectedBytes = substr_replace($expectedBytes, $timeHiAndVersion, 6, 2); diff --git a/tests/Generator/PeclUuidRandomGeneratorTest.php b/tests/Generator/PeclUuidRandomGeneratorTest.php index aaa5d2e..acacf61 100644 --- a/tests/Generator/PeclUuidRandomGeneratorTest.php +++ b/tests/Generator/PeclUuidRandomGeneratorTest.php @@ -4,8 +4,8 @@ declare(strict_types=1); namespace Ramsey\Uuid\Test\Generator; -use AspectMock\Test as AspectMock; use Ramsey\Uuid\Generator\PeclUuidRandomGenerator; +use phpmock\mockery\PHPMockery; use const UUID_TYPE_RANDOM; @@ -22,30 +22,19 @@ class PeclUuidRandomGeneratorTest extends PeclUuidTestCase */ public function testGenerateCreatesUuidUsingPeclUuidMethods(): void { - $create = AspectMock::func('Ramsey\Uuid\Generator', 'uuid_create', $this->uuidString); - $parse = AspectMock::func('Ramsey\Uuid\Generator', 'uuid_parse', $this->uuidBinary); + PHPMockery::mock('Ramsey\Uuid\Generator', 'uuid_create') + ->once() + ->with(UUID_TYPE_RANDOM) + ->andReturn($this->uuidString); + + PHPMockery::mock('Ramsey\Uuid\Generator', 'uuid_parse') + ->once() + ->with($this->uuidString) + ->andReturn($this->uuidBinary); $generator = new PeclUuidRandomGenerator(); $uuid = $generator->generate($this->length); $this->assertSame($this->uuidBinary, $uuid); - $create->verifyInvoked([UUID_TYPE_RANDOM]); - $parse->verifyInvoked([$this->uuidString]); - } - - /** - * This test is for the return type of the generate method - * It ensures that the generate method returns whatever value uuid_parse returns. - */ - public function testGenerateReturnsUuidString(): void - { - $create = AspectMock::func('Ramsey\Uuid\Generator', 'uuid_create', $this->uuidString); - $parse = AspectMock::func('Ramsey\Uuid\Generator', 'uuid_parse', $this->uuidBinary); - $generator = new PeclUuidRandomGenerator(); - $uuid = $generator->generate($this->length); - - $this->assertSame($this->uuidBinary, $uuid); - $create->verifyInvoked([UUID_TYPE_RANDOM]); - $parse->verifyInvoked([$this->uuidString]); } } diff --git a/tests/Generator/PeclUuidTimeGeneratorTest.php b/tests/Generator/PeclUuidTimeGeneratorTest.php index b404e5f..e4c0e20 100644 --- a/tests/Generator/PeclUuidTimeGeneratorTest.php +++ b/tests/Generator/PeclUuidTimeGeneratorTest.php @@ -4,8 +4,8 @@ declare(strict_types=1); namespace Ramsey\Uuid\Test\Generator; -use AspectMock\Test as AspectMock; use Ramsey\Uuid\Generator\PeclUuidTimeGenerator; +use phpmock\mockery\PHPMockery; use const UUID_TYPE_TIME; @@ -17,30 +17,19 @@ class PeclUuidTimeGeneratorTest extends PeclUuidTestCase */ public function testGenerateCreatesUuidUsingPeclUuidMethods(): void { - $create = AspectMock::func('Ramsey\Uuid\Generator', 'uuid_create', $this->uuidString); - $parse = AspectMock::func('Ramsey\Uuid\Generator', 'uuid_parse', $this->uuidBinary); + PHPMockery::mock('Ramsey\Uuid\Generator', 'uuid_create') + ->once() + ->with(UUID_TYPE_TIME) + ->andReturn($this->uuidString); + + PHPMockery::mock('Ramsey\Uuid\Generator', 'uuid_parse') + ->once() + ->with($this->uuidString) + ->andReturn($this->uuidBinary); $generator = new PeclUuidTimeGenerator(); $uuid = $generator->generate(); $this->assertSame($this->uuidBinary, $uuid); - $create->verifyInvoked([UUID_TYPE_TIME]); - $parse->verifyInvoked([$this->uuidString]); - } - - /** - * This test is for the return type of the generate method - * It ensures that the generate method returns whatever value uuid_parse returns. - */ - public function testGenerateReturnsUuidString(): void - { - $create = AspectMock::func('Ramsey\Uuid\Generator', 'uuid_create', $this->uuidString); - $parse = AspectMock::func('Ramsey\Uuid\Generator', 'uuid_parse', $this->uuidBinary); - $generator = new PeclUuidTimeGenerator(); - $uuid = $generator->generate(); - - $this->assertSame($this->uuidBinary, $uuid); - $create->verifyInvoked([UUID_TYPE_TIME]); - $parse->verifyInvoked([$this->uuidString]); } } diff --git a/tests/Generator/RandomBytesGeneratorTest.php b/tests/Generator/RandomBytesGeneratorTest.php index dca6618..1b09b07 100644 --- a/tests/Generator/RandomBytesGeneratorTest.php +++ b/tests/Generator/RandomBytesGeneratorTest.php @@ -4,11 +4,11 @@ declare(strict_types=1); namespace Ramsey\Uuid\Test\Generator; -use AspectMock\Test as AspectMock; use Exception; use Ramsey\Uuid\Exception\RandomSourceException; use Ramsey\Uuid\Generator\RandomBytesGenerator; use Ramsey\Uuid\Test\TestCase; +use phpmock\mockery\PHPMockery; use function hex2bin; @@ -26,23 +26,6 @@ class RandomBytesGeneratorTest extends TestCase ]; } - /** - * @throws Exception - * - * @dataProvider lengthAndHexDataProvider - * @runInSeparateProcess - * @preserveGlobalState disabled - */ - public function testGenerateUsesOpenSsl(int $length, string $hex): void - { - $bytes = hex2bin($hex); - $openSsl = AspectMock::func('Ramsey\Uuid\Generator', 'random_bytes', $bytes); - $generator = new RandomBytesGenerator(); - - $this->assertSame($bytes, $generator->generate($length)); - $openSsl->verifyInvokedOnce([$length]); - } - /** * @throws Exception * @@ -53,8 +36,14 @@ class RandomBytesGeneratorTest extends TestCase public function testGenerateReturnsRandomBytes(int $length, string $hex): void { $bytes = hex2bin($hex); - AspectMock::func('Ramsey\Uuid\Generator', 'random_bytes', $bytes); + + PHPMockery::mock('Ramsey\Uuid\Generator', 'random_bytes') + ->once() + ->with($length) + ->andReturn($bytes); + $generator = new RandomBytesGenerator(); + $this->assertSame($bytes, $generator->generate($length)); } @@ -64,9 +53,10 @@ class RandomBytesGeneratorTest extends TestCase */ public function testGenerateThrowsExceptionWhenExceptionThrownByRandombytes(): void { - AspectMock::func('Ramsey\Uuid\Generator', 'random_bytes', function (): void { - throw new Exception('Could not gather sufficient random data'); - }); + PHPMockery::mock('Ramsey\Uuid\Generator', 'random_bytes') + ->once() + ->with(16) + ->andThrow(new Exception('Could not gather sufficient random data')); $generator = new RandomBytesGenerator(); diff --git a/tests/Provider/Node/RandomNodeProviderTest.php b/tests/Provider/Node/RandomNodeProviderTest.php index bf81815..2af3922 100644 --- a/tests/Provider/Node/RandomNodeProviderTest.php +++ b/tests/Provider/Node/RandomNodeProviderTest.php @@ -4,11 +4,11 @@ declare(strict_types=1); namespace Ramsey\Uuid\Test\Provider\Node; -use AspectMock\Test as AspectMock; use Exception; use Ramsey\Uuid\Exception\RandomSourceException; use Ramsey\Uuid\Provider\Node\RandomNodeProvider; use Ramsey\Uuid\Test\TestCase; +use phpmock\mockery\PHPMockery; use function bin2hex; use function hex2bin; @@ -18,12 +18,6 @@ use function substr; class RandomNodeProviderTest extends TestCase { - protected function tearDown(): void - { - parent::tearDown(); - AspectMock::clean(); - } - /** * @runInSeparateProcess * @preserveGlobalState disabled @@ -33,30 +27,15 @@ class RandomNodeProviderTest extends TestCase $bytes = hex2bin('38a675685d50'); $expectedNode = '39a675685d50'; - $randomBytes = AspectMock::func('Ramsey\Uuid\Provider\Node', 'random_bytes', $bytes); + PHPMockery::mock('Ramsey\Uuid\Provider\Node', 'random_bytes') + ->once() + ->with(6) + ->andReturn($bytes); + $provider = new RandomNodeProvider(); $node = $provider->getNode(); $this->assertSame($expectedNode, $node->toString()); - $randomBytes->verifyInvoked([6]); - } - - /** - * @runInSeparateProcess - * @preserveGlobalState disabled - */ - public function testGetNodeSetsMulticastBit(): void - { - $bytes = hex2bin('38a675685d50'); - - // Expected node has the multicast bit set, and it wasn't set in the bytes. - $expectedNode = '39a675685d50'; - - $randomBytes = AspectMock::func('Ramsey\Uuid\Provider\Node', 'random_bytes', $bytes); - $provider = new RandomNodeProvider(); - - $this->assertSame($expectedNode, $provider->getNode()->toString()); - $randomBytes->verifyInvoked([6]); } /** @@ -71,11 +50,14 @@ class RandomNodeProviderTest extends TestCase // We expect the same hex value for the node. $expectedNode = $bytesHex; - $randomBytes = AspectMock::func('Ramsey\Uuid\Provider\Node', 'random_bytes', $bytes); + PHPMockery::mock('Ramsey\Uuid\Provider\Node', 'random_bytes') + ->once() + ->with(6) + ->andReturn($bytes); + $provider = new RandomNodeProvider(); $this->assertSame($expectedNode, $provider->getNode()->toString()); - $randomBytes->verifyInvoked([6]); } /** @@ -87,11 +69,14 @@ class RandomNodeProviderTest extends TestCase $bytes = hex2bin('100000000001'); $expectedNode = '110000000001'; - $randomBytes = AspectMock::func('Ramsey\Uuid\Provider\Node', 'random_bytes', $bytes); + PHPMockery::mock('Ramsey\Uuid\Provider\Node', 'random_bytes') + ->once() + ->with(6) + ->andReturn($bytes); + $provider = new RandomNodeProvider(); $this->assertSame($expectedNode, $provider->getNode()->toString()); - $randomBytes->verifyInvoked([6]); } public function testGetNodeAlwaysSetsMulticastBit(): void @@ -125,9 +110,9 @@ class RandomNodeProviderTest extends TestCase */ public function testGetNodeThrowsExceptionWhenExceptionThrownByRandombytes(): void { - AspectMock::func('Ramsey\Uuid\Provider\Node', 'random_bytes', function (): void { - throw new Exception('Could not gather sufficient random data'); - }); + PHPMockery::mock('Ramsey\Uuid\Provider\Node', 'random_bytes') + ->once() + ->andThrow(new Exception('Could not gather sufficient random data')); $provider = new RandomNodeProvider(); diff --git a/tests/Provider/Node/SystemNodeProviderTest.php b/tests/Provider/Node/SystemNodeProviderTest.php index 4e98e78..8bf85c2 100644 --- a/tests/Provider/Node/SystemNodeProviderTest.php +++ b/tests/Provider/Node/SystemNodeProviderTest.php @@ -4,12 +4,11 @@ declare(strict_types=1); namespace Ramsey\Uuid\Test\Provider\Node; -use AspectMock\Proxy\FuncProxy; -use AspectMock\Test as AspectMock; use Ramsey\Uuid\Exception\InvalidArgumentException; use Ramsey\Uuid\Exception\NodeException; use Ramsey\Uuid\Provider\Node\SystemNodeProvider; use Ramsey\Uuid\Test\TestCase; +use phpmock\spy\Spy; use function array_shift; use function array_walk; @@ -18,13 +17,15 @@ use function is_array; use function strlen; use function vsprintf; +use const GLOB_NOSORT; + /** * Tests for the SystemNodeProvider class * * The class under test make use of various native functions who's output is * dictated by which environment PHP runs on. Instead of having to run these - * tests on each of these environments, the related functions are mocked (using - * AspectMock). The following functions are concerned: + * tests on each of these environments, the related functions are mocked. The + * following functions are concerned: * * - glob * - constant @@ -55,7 +56,7 @@ class SystemNodeProviderTest extends TestCase private const PROVIDER_NAMESPACE = 'Ramsey\\Uuid\\Provider\\Node'; /** - * @var FuncProxy[] + * @var Spy[] */ private $functionProxies = []; @@ -318,7 +319,7 @@ class SystemNodeProviderTest extends TestCase $fileGetContentsAssert = null; $isReadableAssert = null; if ($os === 'Linux') { - $globBodyAssert = ['/sys/class/net/*/address']; + $globBodyAssert = [['/sys/class/net/*/address', GLOB_NOSORT]]; $fileGetContentsAssert = ['mock address path']; $isReadableAssert = $fileGetContentsAssert; } @@ -427,7 +428,7 @@ class SystemNodeProviderTest extends TestCase if ($os === 'Linux') { $fileGetContentsAssert = [['mock address path 1'], ['mock address path 2']]; - $globBodyAssert = ['/sys/class/net/*/address']; + $globBodyAssert = [['/sys/class/net/*/address', GLOB_NOSORT]]; $passthruBodyAssert = null; $constantBodyAssert = ['PHP_OS']; $iniGetDisableFunctionsAssert = null; @@ -469,7 +470,7 @@ class SystemNodeProviderTest extends TestCase /* Assert */ $this->assertMockFunctions( null, - ['/sys/class/net/*/address'], + [['/sys/class/net/*/address', GLOB_NOSORT]], ['netstat -ie 2>&1'], ['PHP_OS'], ['disable_functions'] @@ -502,7 +503,7 @@ class SystemNodeProviderTest extends TestCase /* Assert */ $this->assertMockFunctions( null, - ['/sys/class/net/*/address'], + [['/sys/class/net/*/address', GLOB_NOSORT]], ['netstat -ie 2>&1'], ['PHP_OS'], ['disable_functions'] @@ -536,7 +537,7 @@ class SystemNodeProviderTest extends TestCase /* Assert */ $this->assertMockFunctions( null, - ['/sys/class/net/*/address'], + [['/sys/class/net/*/address', GLOB_NOSORT]], ['netstat -ie 2>&1'], ['PHP_OS'], ['disable_functions'], @@ -611,7 +612,16 @@ class SystemNodeProviderTest extends TestCase ]; array_walk($mockFunction, function ($body, $key): void { - $this->functionProxies[$key] = AspectMock::func(self::PROVIDER_NAMESPACE, $key, $body); + if (!is_callable($body)) { + $body = function () use ($body) { + return $body; + }; + } + + $spy = new Spy(self::PROVIDER_NAMESPACE, $key, $body); + $spy->enable(); + + $this->functionProxies[$key] = $spy; }); } @@ -621,7 +631,7 @@ class SystemNodeProviderTest extends TestCase * Provide a NULL to assert a function is never called. * * @param array|array>|null $fileGetContentsAssert - * @param array|array>|null $globBodyAssert + * @param array>|null $globBodyAssert * @param array|array>|null $passthruBodyAssert * @param array|array>|null $constantBodyAssert * @param array|array>|null $iniGetDisableFunctionsAssert @@ -646,13 +656,21 @@ class SystemNodeProviderTest extends TestCase array_walk($mockFunctionAsserts, function ($asserts, $key): void { if ($asserts === null) { - $this->functionProxies[$key]->verifyNeverInvoked(); + // Assert the function was never invoked. + $this->assertEmpty($this->functionProxies[$key]->getInvocations()); } elseif (is_array($asserts)) { + // Assert there was at least one invocation for this function. + $this->assertNotEmpty($this->functionProxies[$key]->getInvocations()); + + $invokedArgs = []; + foreach ($this->functionProxies[$key]->getInvocations() as $invocation) { + $invokedArgs[] = $invocation->getArguments(); + } + foreach ($asserts as $assert) { - if (!is_array($assert)) { - $assert = [$assert]; - } - $this->functionProxies[$key]->verifyInvoked($assert); + // Assert these args were used to invoke the function. + $assert = is_array($assert) ? $assert : [$assert]; + $this->assertContains($assert, $invokedArgs); } } else { $error = vsprintf( diff --git a/tests/TestCase.php b/tests/TestCase.php index 84228fe..ed22f93 100644 --- a/tests/TestCase.php +++ b/tests/TestCase.php @@ -4,7 +4,6 @@ declare(strict_types=1); namespace Ramsey\Uuid\Test; -use AspectMock\Test as AspectMock; use Mockery; use PHPUnit\Framework\TestCase as PhpUnitTestCase; @@ -17,12 +16,14 @@ class TestCase extends PhpUnitTestCase protected function tearDown(): void { parent::tearDown(); - AspectMock::clean(); Mockery::close(); } public static function isLittleEndianSystem(): bool { - return current(unpack('v', pack('S', 0x00FF))) === 0x00FF; + /** @var array $unpacked */ + $unpacked = unpack('v', pack('S', 0x00FF)); + + return current($unpacked) === 0x00FF; } } diff --git a/tests/bootstrap.php b/tests/bootstrap.php index 40eef3f..c0393bc 100644 --- a/tests/bootstrap.php +++ b/tests/bootstrap.php @@ -11,22 +11,5 @@ error_reporting(E_ALL & ~E_DEPRECATED); // Ensure floating-point precision is set to 14 (the default) for tests. ini_set('precision', '14'); -use AspectMock\Kernel; - require_once __DIR__ . '/../vendor/autoload.php'; // composer autoload require_once __DIR__ . '/phpstan-bootstrap.php'; - -$cacheDir = __DIR__ . '/../build/cache/goaop'; -if (!is_dir($cacheDir)) { - if (mkdir($cacheDir, 0775, true) === false) { - echo "\n[ERROR] Unable to create cache directory at {$cacheDir}\n\n"; - exit(1); - } -} - -$kernel = Kernel::getInstance(); -$kernel->init([ - 'debug' => true, - 'cacheDir' => $cacheDir, - 'includePaths' => [__DIR__ . '/../src'] -]); diff --git a/tests/phpstan-tests.neon b/tests/phpstan-tests.neon index c31d53e..1973ce3 100644 --- a/tests/phpstan-tests.neon +++ b/tests/phpstan-tests.neon @@ -3,7 +3,7 @@ parameters: level: max paths: - . - autoload_files: + bootstrapFiles: - ./phpstan-bootstrap.php checkMissingIterableValueType: false reportUnmatchedIgnoredErrors: false diff --git a/tests/phpstan.neon b/tests/phpstan.neon index 405d2d8..9a01671 100644 --- a/tests/phpstan.neon +++ b/tests/phpstan.neon @@ -5,7 +5,7 @@ parameters: - ../src checkMissingIterableValueType: false reportUnmatchedIgnoredErrors: false - autoload_files: + bootstrapFiles: - ./phpstan-bootstrap.php ignoreErrors: - diff --git a/tests/psalm-baseline.xml b/tests/psalm-baseline.xml index be0e7de..2744786 100644 --- a/tests/psalm-baseline.xml +++ b/tests/psalm-baseline.xml @@ -1,48 +1,52 @@ - + - new DegradedTimeConverter() DegradedUuid + new DegradedTimeConverter() + + $this + $this + + + + + + $this + + + + + $this + $this + BigNumberConverter + + + $this + $this + + BigNumberTimeConverter - - - $uuidTime - $uuidTime - - - - - $uuid - - - string - - - uuid_parse($uuid) - - - - - $uuid - - - string - - - uuid_parse($uuid) - + + + $calculator + $dceSecurityGenerator + $numberConverter + $timeConverter + $timeGenerator + $timeProvider + @@ -51,12 +55,26 @@ uuid_parse + + + $this + $this + $this + + + + + $this + $this + $this + + - shell_exec('id -u') shell_exec('id -g') - shell_exec('whoami /user /fo csv /nh') + shell_exec('id -u') shell_exec('net user %username% | findstr /b /i "Local Group Memberships"') + shell_exec('whoami /user /fo csv /nh') shell_exec('wmic group get name,sid | findstr /b /i ' . escapeshellarg($firstGroup)) @@ -64,9 +82,31 @@ $macs - - $node - + + $macs + + + $macs[] + + + + + $this + $this + $this + $this + $this + $this + $this + $this + $this + $this + $this + $this + $this + $this + $this + @@ -78,4 +118,30 @@ getFactory + + + $this->codec + $this->codec + $this->codec + $this->isDefaultFeatureSet + $this->nameGenerator + $this->numberConverter + $this->uuidBuilder + + + $this + $this + $this + $this + $this + $this + $this + $this + $this + $this + $this + $this + $this + +