diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 0000000..60b603d --- /dev/null +++ b/.editorconfig @@ -0,0 +1,24 @@ +# https://EditorConfig.org + +root = true + +[*] +indent_style = space +# Reduce tab size on GitHub +indent_size = 4 +end_of_line = lf +charset = utf-8 +trim_trailing_whitespace = true +insert_final_newline = true +block_comment_start = /* +block_comment = * +block_comment_end = */ + +[{*.yml,*.yaml}] +indent_size = 2 + +[*.md] +trim_trailing_whitespace = false + +[Makefile] +indent_style = tab diff --git a/.gitattributes b/.gitattributes index 2c7cf47..9110993 100644 --- a/.gitattributes +++ b/.gitattributes @@ -2,14 +2,14 @@ /.github export-ignore /tests export-ignore +/.editorconfig export-ignore /.gitattributes export-ignore /.gitignore export-ignore /CODE_OF_CONDUCT.md export-ignore +/deptrac.yaml export-ignore /ecs.php export-ignore /infection.json.dist export-ignore /Makefile export-ignore /phpstan.neon export-ignore /phpunit.xml.dist export-ignore -/README.md export-ignore /rector.php export-ignore -/SECURITY.md export-ignore diff --git a/.github/CONTRIBUTING.md b/.github/CONTRIBUTING.md index 21ab573..7cc67ce 100644 --- a/.github/CONTRIBUTING.md +++ b/.github/CONTRIBUTING.md @@ -11,9 +11,14 @@ Few rules to ease code reviews and merges: - You MUST write (or update) unit tests when bugs are fixed or features are added. - You SHOULD write documentation. -To contribute use [Pull Requests](https://help.github.com/articles/using-pull-requests), please, write commit messages that make sense, and rebase your branch before submitting your PR. +We use [Git-Flow](http://jeffkreeftmeijer.com/2010/why-arent-you-using-git-flow/) to automate our git branching +workflow. -May be asked to squash your commits too. This is used to "clean" your Pull Request before merging it, avoiding commits such as fix tests, fix 2, fix 3, etc. +To contribute use [Pull Requests](https://help.github.com/articles/using-pull-requests), please, write commit messages +that make sense, and rebase your branch before submitting your PR. + +May be asked to squash your commits too. This is used to "clean" your Pull Request before merging it, avoiding commits +such as fix tests, fix 2, fix 3, etc. Run test suite ------------ @@ -21,7 +26,3 @@ Run test suite * install composer: `curl -s http://getcomposer.org/installer | php` * install dependencies: `php composer.phar install` * run tests: `vendor/bin/phpunit` -* check and fix coding standards: - * `vendor/bin/phpstan analyse` - * `vendor/bin/rector process` - * `vendor/bin/ecs check --fix` diff --git a/.github/ISSUE_TEMPLATE/1_Bug_report.md b/.github/ISSUE_TEMPLATE/1_Bug_report.md deleted file mode 100644 index 3a3e9fd..0000000 --- a/.github/ISSUE_TEMPLATE/1_Bug_report.md +++ /dev/null @@ -1,21 +0,0 @@ ---- -name: 🐛 Bug Report -about: ⚠️ See below for security reports -labels: Bug - ---- - -**Version(s) affected**: x.y.z - -**Description** - - -**How to reproduce** - - -**Possible Solution** - - -**Additional context** - diff --git a/.github/ISSUE_TEMPLATE/1_Bug_report.yaml b/.github/ISSUE_TEMPLATE/1_Bug_report.yaml new file mode 100644 index 0000000..d3f26cf --- /dev/null +++ b/.github/ISSUE_TEMPLATE/1_Bug_report.yaml @@ -0,0 +1,42 @@ +name: 🐛 Bug Report +description: ⚠️ NEVER report security issues, email security AT spomky-labs.com instead +labels: Bug +body: + - type: input + id: affected-versions + attributes: + label: Version(s) affected + placeholder: x.y.z + validations: + required: true + - type: textarea + id: description + attributes: + label: Description + description: A clear and concise description of the problem + validations: + required: true + - type: textarea + id: how-to-reproduce + attributes: + label: How to reproduce + description: | + ⚠️ This is the most important part of the report ⚠️ + Without a way to easily reproduce your issue, there is little chance we will be able to help you and work on a fix. + Please, take the time to show us some code and/or config that is needed for others to reproduce the problem easily. + Most of the time, creating a "bug reproducer" is the best way to help us and increases the chances someone + will have a look at it. + validations: + required: true + - type: textarea + id: possible-solution + attributes: + label: Possible Solution + description: | + Optional: only if you have suggestions on a fix/reason for the bug + Don't hesitate to create a pull request with your solution, it helps get faster feedback. + - type: textarea + id: additional-context + attributes: + label: Additional Context + description: "Optional: any other context about the problem: log messages, screenshots, etc." diff --git a/.github/ISSUE_TEMPLATE/2_Feature_request.md b/.github/ISSUE_TEMPLATE/2_Feature_request.md deleted file mode 100644 index 8ffd974..0000000 --- a/.github/ISSUE_TEMPLATE/2_Feature_request.md +++ /dev/null @@ -1,12 +0,0 @@ ---- -name: 🚀 Feature Request -about: Ideas for new features and improvements - ---- - -**Description** - - -**Example** - diff --git a/.github/ISSUE_TEMPLATE/2_Feature_request.yaml b/.github/ISSUE_TEMPLATE/2_Feature_request.yaml new file mode 100644 index 0000000..52b3de7 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/2_Feature_request.yaml @@ -0,0 +1,17 @@ +name: 🚀 Feature Request +description: RFC and ideas for new features and improvements +body: + - type: textarea + id: description + attributes: + label: Description + description: A clear and concise description of the new feature + validations: + required: true + - type: textarea + id: example + attributes: + label: Example + description: | + A simple example of the new feature in action (include PHP code, YAML config, etc.) + If the new feature changes an existing feature, include a simple before/after comparison. diff --git a/.github/ISSUE_TEMPLATE/3_Documentation.yaml b/.github/ISSUE_TEMPLATE/3_Documentation.yaml new file mode 100644 index 0000000..1c5ac89 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/3_Documentation.yaml @@ -0,0 +1,10 @@ +name: 📖 Documentation Issue +description: To report typo or obsolete section in the documentation +body: + - type: textarea + id: description + attributes: + label: Description + description: A clear and concise description of the error you found in the documentation + validations: + required: true diff --git a/.github/ISSUE_TEMPLATE/3_Documentation_issue.md b/.github/ISSUE_TEMPLATE/3_Documentation_issue.md deleted file mode 100644 index 26cd199..0000000 --- a/.github/ISSUE_TEMPLATE/3_Documentation_issue.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -name: 📖 Documentation Issue -about: To report typo or obsolete section in the documentation - ---- diff --git a/.github/ISSUE_TEMPLATE/config.yml b/.github/ISSUE_TEMPLATE/config.yml index dde06cf..d9e01de 100644 --- a/.github/ISSUE_TEMPLATE/config.yml +++ b/.github/ISSUE_TEMPLATE/config.yml @@ -2,4 +2,7 @@ blank_issues_enabled: false contact_links: - name: Support Question url: https://spomky-labs.com/contact/ - about: We use GitHub issues only to discuss about bugs and new features. For this kind of questions about using the library, please use Stackoverflow (or similar) or send a quote request at https://spomky-labs.com/contact/ + about: | + We use GitHub issues only to discuss about bugs and new features. + For this kind of questions about using the framework or third-party bundles, + please email us contact AT spomky-labs.com for quoting diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md index 1beb0a3..029817b 100644 --- a/.github/PULL_REQUEST_TEMPLATE.md +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -1,19 +1,17 @@ -| Q | A -| ------------- | --- -| Branch? | -| Bug fix? | yes/no -| New feature? | yes/no -| Deprecations? | yes/no -| Tickets | Fix #... -| License | MIT +Target branch: +Resolves issue # + + +- [ ] It is a Bug fix +- [ ] It is a New feature +- [ ] Breaks BC +- [ ] Includes Deprecations + \ No newline at end of file +Please consider the following requirement: +* Modification of existing tests should be avoided unless deemed necessary. +* You MUST never open a PR related to a security issue. Contact Spomky in private at https://gitter.im/Spomky/ +--> diff --git a/.github/dependabot.yml b/.github/dependabot.yml new file mode 100644 index 0000000..ae2faa4 --- /dev/null +++ b/.github/dependabot.yml @@ -0,0 +1,19 @@ +version: 2 +updates: + - package-ecosystem: "composer" + directory: "/" + schedule: + interval: "weekly" + day: "friday" + versioning-strategy: "widen" + open-pull-requests-limit: 20 + allow: + - dependency-type: all + labels: [ "Dependencies" ] + + - package-ecosystem: "github-actions" + directory: "/" + schedule: + interval: "monthly" + open-pull-requests-limit: 20 + labels: [ "Dependencies" ] diff --git a/.github/workflows/coding-standards.yml b/.github/workflows/coding-standards.yml deleted file mode 100644 index 013006c..0000000 --- a/.github/workflows/coding-standards.yml +++ /dev/null @@ -1,32 +0,0 @@ -name: Coding Standards - -on: [push] - -jobs: - tests: - runs-on: ${{ matrix.operating-system }} - strategy: - matrix: - operating-system: [ubuntu-latest] - php-versions: ['8.1'] - name: PHP ${{ matrix.php-versions }} Test on ${{ matrix.operating-system }} - - steps: - - name: Checkout - uses: actions/checkout@v2 - with: - ref: ${{ github.head_ref }} - - - name: Setup PHP, with composer and extensions - uses: shivammathur/setup-php@v2 - with: - php-version: ${{ matrix.php-versions }} - extensions: json, mbstring, openssl - coverage: xdebug - - - name: Install Composer dependencies - run: | - composer update --no-progress --no-suggest --prefer-dist --optimize-autoloader - - - name: ECS - run: make coding-standards diff --git a/.github/workflows/dependency-review.yml b/.github/workflows/dependency-review.yml deleted file mode 100644 index 8966511..0000000 --- a/.github/workflows/dependency-review.yml +++ /dev/null @@ -1,20 +0,0 @@ -# Dependency Review Action -# -# This Action will scan dependency manifest files that change as part of a Pull Request, surfacing known-vulnerable versions of the packages declared or updated in the PR. Once installed, if the workflow run is marked as required, PRs introducing known-vulnerable packages will be blocked from merging. -# -# Source repository: https://github.com/actions/dependency-review-action -# Public documentation: https://docs.github.com/en/code-security/supply-chain-security/understanding-your-software-supply-chain/about-dependency-review#dependency-review-enforcement -name: 'Dependency Review' -on: [pull_request] - -permissions: - contents: read - -jobs: - dependency-review: - runs-on: ubuntu-latest - steps: - - name: 'Checkout Repository' - uses: actions/checkout@v3 - - name: 'Dependency Review' - uses: actions/dependency-review-action@v1 diff --git a/.github/workflows/integrate.yml b/.github/workflows/integrate.yml new file mode 100644 index 0000000..57b43d4 --- /dev/null +++ b/.github/workflows/integrate.yml @@ -0,0 +1,230 @@ +# yaml-language-server: $schema=https://json.schemastore.org/github-workflow + +name: "Integrate" + +on: + push: + branches: + - "*.x" + pull_request: null + +jobs: + byte_level: + name: "0️⃣ Byte-level" + runs-on: "ubuntu-latest" + steps: + - name: "Checkout code" + uses: "actions/checkout@v3" + + - name: "Check file permissions" + run: | + test "$(find . -type f -not -path './.git/*' -executable)" == "" + + - name: "Find non-printable ASCII characters" + run: | + ! LC_ALL=C.UTF-8 find ./src -type f -name "*.php" -print0 | xargs -0 -- grep -PHn "[^ -~]" + + syntax_errors: + name: "1️⃣ Syntax errors" + runs-on: "ubuntu-latest" + steps: + - name: "Set up PHP" + uses: "shivammathur/setup-php@v2" + with: + php-version: "8.1" + coverage: "none" + + - name: "Checkout code" + uses: "actions/checkout@v3" + + - name: "Install dependencies" + uses: "ramsey/composer-install@v2" + with: + dependency-versions: "highest" + + - name: "Check source code for syntax errors" + run: "composer exec -- parallel-lint src/ tests/" + + unit_tests: + name: "2️⃣ Unit and functional tests" + needs: + - "byte_level" + - "syntax_errors" + strategy: + matrix: + operating-system: + - "ubuntu-latest" + php-version: + - "8.1" + dependencies: + - "lowest" + - "highest" + runs-on: ${{ matrix.operating-system }} + steps: + - name: "Set up PHP" + uses: "shivammathur/setup-php@v2" + with: + php-version: "${{ matrix.php-version }}" + extensions: "ctype, dom, json, libxml, mbstring, openssl, phar, simplexml, tokenizer, xml, xmlwriter" + coverage: "xdebug" + + - name: "Checkout code" + uses: "actions/checkout@v3" + + - name: "Install dependencies" + uses: "ramsey/composer-install@v2" + with: + dependency-versions: "${{ matrix.dependencies }}" + composer-options: "--optimize-autoloader" + + - name: "Execute tests (PHP)" + run: "make ci-cc" + + # - name: Send coverage to Coveralls + # if: "matrix.php-version == '8.1' && matrix.dependencies == 'highest'" + # env: + # COVERALLS_REPO_TOKEN: "${{ secrets.GITHUB_TOKEN }}" + # run: | + # wget "https://github.com/php-coveralls/php-coveralls/releases/download/v2.5.2/php-coveralls.phar" + # php ./php-coveralls.phar -v + + static_analysis: + name: "3️⃣ Static Analysis" + needs: + - "byte_level" + - "syntax_errors" + runs-on: "ubuntu-latest" + steps: + - name: "Set up PHP" + uses: "shivammathur/setup-php@v2" + with: + php-version: "8.1" + extensions: "ctype, dom, json, libxml, mbstring, openssl, phar, simplexml, tokenizer, xml, xmlwriter" + coverage: "none" + + - name: "Checkout code" + uses: "actions/checkout@v3" + + - name: "Validate Composer configuration" + run: "composer validate --strict" + + - name: "Install dependencies" + uses: "ramsey/composer-install@v2" + with: + dependency-versions: "highest" + composer-options: "--optimize-autoloader" + + - name: "Check PSR-4 mapping" + run: "composer dump-autoload --optimize --strict-psr" + + - name: "Execute static analysis" + run: "make st" + + coding_standards: + name: "4️⃣ Coding Standards" + needs: + - "byte_level" + - "syntax_errors" + runs-on: "ubuntu-latest" + steps: + - name: "Set up PHP" + uses: "shivammathur/setup-php@v2" + with: + php-version: "8.1" + extensions: "ctype, dom, json, libxml, mbstring, openssl, phar, simplexml, tokenizer, xml, xmlwriter" + coverage: "none" + + - name: "Checkout code" + uses: "actions/checkout@v3" + + - name: "Check adherence to EditorConfig" + uses: "greut/eclint-action@v0" + + - name: "Install dependencies" + uses: "ramsey/composer-install@v2" + with: + dependency-versions: "highest" + composer-options: "--optimize-autoloader" + + - name: "Check coding style" + run: "make ci-cs" + + - name: "Deptrac" + run: | + vendor/bin/deptrac analyse --fail-on-uncovered --no-cache + + mutation_testing: + name: "5️⃣ Mutation Testing" + needs: + - "byte_level" + - "syntax_errors" + runs-on: "ubuntu-latest" + steps: + - name: "Set up PHP" + uses: "shivammathur/setup-php@v2" + with: + php-version: "8.1" + extensions: "ctype, dom, json, libxml, mbstring, openssl, phar, simplexml, tokenizer, xml, xmlwriter" + coverage: "xdebug" + + - name: "Checkout code" + uses: "actions/checkout@v3" + + - name: "Fetch Git base reference" + run: "git fetch --depth=1 origin ${GITHUB_BASE_REF}" + + - name: "Install dependencies" + uses: "ramsey/composer-install@v2" + with: + dependency-versions: "highest" + composer-options: "--optimize-autoloader" + + - name: "Execute Infection" + run: "make ci-mu" + + rector_checkstyle: + name: "6️⃣ Rector Checkstyle" + needs: + - "byte_level" + - "syntax_errors" + runs-on: "ubuntu-latest" + steps: + - name: "Set up PHP" + uses: "shivammathur/setup-php@v2" + with: + php-version: "8.1" + extensions: "ctype, dom, json, libxml, mbstring, openssl, phar, simplexml, tokenizer, xml, xmlwriter" + coverage: "xdebug" + + - name: "Checkout code" + uses: "actions/checkout@v3" + + - name: "Fetch Git base reference" + run: "git fetch --depth=1 origin ${GITHUB_BASE_REF}" + + - name: "Install dependencies" + uses: "ramsey/composer-install@v2" + with: + dependency-versions: "highest" + composer-options: "--optimize-autoloader" + + - name: "Execute Rector" + run: "make rector" + + exported_files: + name: "7️⃣ Exported files" + needs: + - "byte_level" + - "syntax_errors" + runs-on: "ubuntu-20.04" + steps: + - name: "Checkout code" + uses: "actions/checkout@v3" + + - name: "Check exported files" + run: | + EXPECTED="LICENSE,README.md,SECURITY.md,composer.json" + CURRENT="$(git archive HEAD | tar --list --exclude="src" --exclude="src/*" | paste -s -d ",")" + echo "CURRENT =${CURRENT}" + echo "EXPECTED=${EXPECTED}" + test "${CURRENT}" == "${EXPECTED}" diff --git a/.github/workflows/merge-me.yml b/.github/workflows/merge-me.yml new file mode 100644 index 0000000..1796365 --- /dev/null +++ b/.github/workflows/merge-me.yml @@ -0,0 +1,28 @@ +name: Merge me! + +on: + check_suite: + types: + - completed + +jobs: + merge-me: + name: Merge me! + runs-on: ubuntu-latest + steps: + - name: Merge me! + uses: ridedott/merge-me-action@v2.10.35 + with: + # Depending on branch protection rules, a manually populated + # `GITHUB_TOKEN_WORKAROUND` environment variable with permissions to + # push to a protected branch must be used. This variable can have an + # arbitrary name, as an example, this repository uses + # `GITHUB_TOKEN_DOTTBOTT`. + # + # When using a custom token, it is recommended to leave the following + # comment for other developers to be aware of the reasoning behind it: + # + # This must be used as GitHub Actions token does not support + # pushing to protected branches. + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + MERGE_METHOD: MERGE diff --git a/.github/workflows/mutation-tests.yml b/.github/workflows/mutation-tests.yml deleted file mode 100644 index 55fa750..0000000 --- a/.github/workflows/mutation-tests.yml +++ /dev/null @@ -1,35 +0,0 @@ -name: Mutation Testing - -on: [push] - -jobs: - tests: - runs-on: ${{ matrix.operating-system }} - strategy: - matrix: - operating-system: [ubuntu-latest] - php-versions: ['8.1'] - name: PHP ${{ matrix.php-versions }} Test on ${{ matrix.operating-system }} - - steps: - - name: Checkout - uses: actions/checkout@v2 - with: - ref: ${{ github.head_ref }} - - - name: Setup PHP, with composer and extensions - uses: shivammathur/setup-php@v2 - with: - php-version: ${{ matrix.php-versions }} - extensions: json, mbstring, openssl - coverage: xdebug - - - name: Install Composer dependencies - run: | - composer update --no-progress --no-suggest --prefer-dist --optimize-autoloader - - - name: Fetch Git base reference - run: git fetch --depth=1 origin $GITHUB_BASE_REF - - - name: Infection - run: make mutation-tests-github diff --git a/.github/workflows/rector_checkstyle.yaml b/.github/workflows/rector_checkstyle.yaml deleted file mode 100644 index 072b133..0000000 --- a/.github/workflows/rector_checkstyle.yaml +++ /dev/null @@ -1,29 +0,0 @@ -name: Rector Checkstyle - -on: [push] - -jobs: - tests: - runs-on: ${{ matrix.operating-system }} - strategy: - matrix: - operating-system: [ ubuntu-latest ] - php-versions: ['8.1'] - steps: - - name: Checkout - uses: actions/checkout@v2 - with: - ref: ${{ github.head_ref }} - - - name: Setup PHP, with composer and extensions - uses: shivammathur/setup-php@v2 - with: - php-version: ${{ matrix.php-versions }} - extensions: json, mbstring, openssl - coverage: none - - - name: Install Composer dependencies - run: composer update --no-progress --no-suggest --prefer-dist --optimize-autoloader - - - name: Rector - run: make rector diff --git a/.github/workflows/release-on-milestone-closed.yml b/.github/workflows/release-on-milestone-closed.yml new file mode 100644 index 0000000..a5f1511 --- /dev/null +++ b/.github/workflows/release-on-milestone-closed.yml @@ -0,0 +1,72 @@ +# https://help.github.com/en/categories/automating-your-workflow-with-github-actions + +name: "Automatic Releases" + +on: + milestone: + types: + - "closed" + +jobs: + release: + name: "GIT tag, release & create merge-up PR" + runs-on: ubuntu-latest + + steps: + - name: "Checkout" + uses: "actions/checkout@v3" + + - name: "Release" + uses: "laminas/automatic-releases@1.19.0" + with: + command-name: "laminas:automatic-releases:release" + env: + "SHELL_VERBOSITY": "3" + "GITHUB_TOKEN": ${{ secrets.ORGANIZATION_ADMIN_TOKEN }} + "SIGNING_SECRET_KEY": ${{ secrets.SIGNING_SECRET_KEY }} + "GIT_AUTHOR_NAME": ${{ secrets.GIT_AUTHOR_NAME }} + "GIT_AUTHOR_EMAIL": ${{ secrets.GIT_AUTHOR_EMAIL }} + + - name: "Create Merge-Up Pull Request" + uses: "laminas/automatic-releases@1.19.0" + with: + command-name: "laminas:automatic-releases:create-merge-up-pull-request" + env: + "SHELL_VERBOSITY": "3" + "GITHUB_TOKEN": ${{ secrets.GITHUB_TOKEN }} + "SIGNING_SECRET_KEY": ${{ secrets.SIGNING_SECRET_KEY }} + "GIT_AUTHOR_NAME": ${{ secrets.GIT_AUTHOR_NAME }} + "GIT_AUTHOR_EMAIL": ${{ secrets.GIT_AUTHOR_EMAIL }} + + - name: "Create and/or Switch to new Release Branch" + uses: "laminas/automatic-releases@1.19.0" + with: + command-name: "laminas:automatic-releases:switch-default-branch-to-next-minor" + env: + "SHELL_VERBOSITY": "3" + "GITHUB_TOKEN": ${{ secrets.ORGANIZATION_ADMIN_TOKEN }} + "SIGNING_SECRET_KEY": ${{ secrets.SIGNING_SECRET_KEY }} + "GIT_AUTHOR_NAME": ${{ secrets.GIT_AUTHOR_NAME }} + "GIT_AUTHOR_EMAIL": ${{ secrets.GIT_AUTHOR_EMAIL }} + + - name: "Bump Changelog Version On Originating Release Branch" + uses: "laminas/automatic-releases@1.19.0" + with: + command-name: "laminas:automatic-releases:bump-changelog" + env: + "SHELL_VERBOSITY": "3" + "GITHUB_TOKEN": ${{ secrets.GITHUB_TOKEN }} + "SIGNING_SECRET_KEY": ${{ secrets.SIGNING_SECRET_KEY }} + "GIT_AUTHOR_NAME": ${{ secrets.GIT_AUTHOR_NAME }} + "GIT_AUTHOR_EMAIL": ${{ secrets.GIT_AUTHOR_EMAIL }} + + - name: "Create new milestones" + uses: "laminas/automatic-releases@1.19.0" + with: + command-name: "laminas:automatic-releases:create-milestones" + env: + "SHELL_VERBOSITY": "3" + "GITHUB_TOKEN": ${{ secrets.GITHUB_TOKEN }} + "SIGNING_SECRET_KEY": ${{ secrets.SIGNING_SECRET_KEY }} + "GIT_AUTHOR_NAME": ${{ secrets.GIT_AUTHOR_NAME }} + "GIT_AUTHOR_EMAIL": ${{ secrets.GIT_AUTHOR_EMAIL }} diff --git a/.github/workflows/static-analyze.yml b/.github/workflows/static-analyze.yml deleted file mode 100644 index f5d265a..0000000 --- a/.github/workflows/static-analyze.yml +++ /dev/null @@ -1,32 +0,0 @@ -name: Static Analyze - -on: [push] - -jobs: - tests: - runs-on: ${{ matrix.operating-system }} - strategy: - matrix: - operating-system: [ubuntu-latest] - php-versions: ['8.1'] - name: PHP ${{ matrix.php-versions }} Test on ${{ matrix.operating-system }} - - steps: - - name: Checkout - uses: actions/checkout@v2 - with: - ref: ${{ github.head_ref }} - - - name: Setup PHP, with composer and extensions - uses: shivammathur/setup-php@v2 - with: - php-version: ${{ matrix.php-versions }} - extensions: json, mbstring, openssl - coverage: xdebug - - - name: Install Composer dependencies - run: | - composer update --no-progress --no-suggest --prefer-dist --optimize-autoloader - - - name: PHPStan - run: make static-analyse diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml deleted file mode 100644 index 14cd700..0000000 --- a/.github/workflows/tests.yml +++ /dev/null @@ -1,32 +0,0 @@ -name: Unit and Functional Tests - -on: [push] - -jobs: - tests: - runs-on: ${{ matrix.operating-system }} - strategy: - matrix: - operating-system: [ ubuntu-latest ] - php-versions: ['8.0', '8.1'] - name: PHP ${{ matrix.php-versions }} Test on ${{ matrix.operating-system }} - - steps: - - name: Checkout - uses: actions/checkout@v2 - with: - ref: ${{ github.head_ref }} - - - name: Setup PHP, with composer and extensions - uses: shivammathur/setup-php@v2 - with: - php-version: ${{ matrix.php-versions }} - extensions: json, mbstring, openssl - coverage: xdebug - - - name: Install Composer dependencies - run: | - composer update --no-progress --no-suggest --prefer-dist --optimize-autoloader - - - name: Run tests - run: make tests diff --git a/.gitignore b/.gitignore index 8f6506a..8da2f5c 100644 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,10 @@ -/vendor/ +.phpunit.result.cache +report.md +*.cache +*.log +node_modules +yarn.lock +yarn-error.log /composer.lock -/*cache -/build -/infection.log \ No newline at end of file +/vendor +infection.txt diff --git a/Makefile b/Makefile index 0595bb9..aa9acad 100644 --- a/Makefile +++ b/Makefile @@ -1,51 +1,48 @@ -.PHONY: code-coverage -code-coverage: vendor ## Show test coverage rates (console) - vendor/bin/phpunit --coverage-text - -.PHONY: coverage -coverage: vendor ## Show test coverage rates (HTML) - vendor/bin/phpunit --coverage-html ./build - -.PHONY: fix-cs -fix-cs: vendor ## Fix all files using defined PHP-CS-FIXER rules - vendor/bin/php-cs-fixer fix - -.PHONY: coding-standards -coding-standards: vendor ## Check all files using ECS rules - vendor/bin/ecs check +mu: vendor ## Mutation tests + vendor/bin/infection -s --threads=$$(nproc) --min-msi=3 --min-covered-msi=58 -.PHONY: tests tests: vendor ## Run all tests vendor/bin/phpunit --color -vendor: composer.json composer.lock - composer validate - composer install +cc: vendor ## Show test coverage rates (HTML) + vendor/bin/phpunit --coverage-html ./build + +cs: vendor ## Fix all files using defined ECS rules + vendor/bin/ecs check --fix -.PHONY: tu tu: vendor ## Run only unit tests vendor/bin/phpunit --color --group Unit -.PHONY: tf +ti: vendor ## Run only integration tests + vendor/bin/phpunit --color --group Integration + tf: vendor ## Run only functional tests vendor/bin/phpunit --color --group Functional -.PHONY: static-analyse -static-analyse: vendor ## Run static analyse +st: vendor ## Run static analyse vendor/bin/phpstan analyse -.PHONY: rector -rector: vendor ## Check all files using Rector - vendor/bin/rector process --ansi --dry-run -v -.PHONY: mutation-tests -mutation-tests: vendor ## Mutation tests - vendor/bin/infection -s --threads=$(nproc) --min-msi=64 --min-covered-msi=74 +################################################ + +ci-mu: vendor ## Mutation tests (for Github only) + vendor/bin/infection --logger-github -s --threads=$$(nproc) --min-msi=3 --min-covered-msi=58 + +ci-cc: vendor ## Show test coverage rates (console) + vendor/bin/phpunit --coverage-text + +ci-cs: vendor ## Check all files using defined ECS rules + vendor/bin/ecs check + +################################################ + -.PHONY: mutation-tests-github -mutation-tests-github: vendor ## Mutation tests (for Github only) - vendor/bin/infection --logger-github --git-diff-filter=AM -s --threads=$(nproc) --min-msi=64 --min-covered-msi=74 +vendor: composer.json composer.lock + composer validate + composer install +rector: vendor ## Check all files using Rector + vendor/bin/rector process --ansi --dry-run --xdebug .DEFAULT_GOAL := help help: diff --git a/composer.json b/composer.json index 7a9d7e2..473a148 100644 --- a/composer.json +++ b/composer.json @@ -25,7 +25,7 @@ }, "require": { "php": ">=8.0", - "brick/math": "^0.9|^0.10", + "brick/math": "^0.9|^0.10|^0.11", "ext-mbstring": "*" }, "require-dev": { @@ -38,11 +38,13 @@ "phpstan/phpstan-deprecation-rules": "^1.0", "phpstan/phpstan-phpunit": "^1.0", "phpstan/phpstan-strict-rules": "^1.0", - "phpunit/phpunit": "^9.5", + "phpunit/phpunit": "^10.0", "rector/rector": "^0.15", "roave/security-advisories": "dev-latest", "symfony/var-dumper": "^6.0", - "symplify/easy-coding-standard": "^11.0" + "symplify/easy-coding-standard": "^11.1", + "php-parallel-lint/php-parallel-lint": "^1.3", + "qossmic/deptrac-shim": "^1.0" }, "config": { "sort-packages": true, diff --git a/deptrac.yaml b/deptrac.yaml new file mode 100644 index 0000000..7573742 --- /dev/null +++ b/deptrac.yaml @@ -0,0 +1,14 @@ +parameters: + paths: + - './src' + layers: + - name: 'CBOR' + collectors: + - type: 'className' + regex: '^CBO\\' + - name: 'Vendors' + collectors: + - { type: className, regex: '^Brick\\' } + ruleset: + CBOR: + - Vendors diff --git a/infection.json.dist b/infection.json.dist index c74bf4e..a6235ba 100644 --- a/infection.json.dist +++ b/infection.json.dist @@ -17,4 +17,4 @@ } } } -} \ No newline at end of file +} diff --git a/phpunit.xml.dist b/phpunit.xml.dist index 072b72b..0769eb4 100644 --- a/phpunit.xml.dist +++ b/phpunit.xml.dist @@ -1,31 +1,23 @@ - - - ./src - - - - - ./tests/ - - - - - - - - + + + ./src + + + + + ./tests/ + + + + + + + + diff --git a/rector.php b/rector.php index d726517..8f09dd1 100644 --- a/rector.php +++ b/rector.php @@ -4,6 +4,8 @@ use Rector\Config\RectorConfig; use Rector\Core\ValueObject\PhpVersion; +use Rector\PHPUnit\Set\PHPUnitLevelSetList; +use Rector\PHPUnit\Set\PHPUnitSetList; use Rector\Set\ValueObject\LevelSetList; use Rector\Set\ValueObject\SetList; use Rector\Symfony\Set\SymfonySetList; @@ -12,8 +14,14 @@ $config->import(SetList::DEAD_CODE); $config->import(LevelSetList::UP_TO_PHP_80); $config->import(SymfonySetList::SYMFONY_CODE_QUALITY); + $config->import(PHPUnitLevelSetList::UP_TO_PHPUNIT_100); + $config->import(PHPUnitSetList::PHPUNIT_CODE_QUALITY); + $config->import(PHPUnitSetList::PHPUNIT_EXCEPTION); + $config->import(PHPUnitSetList::PHPUNIT_SPECIFIC_METHOD); + $config->import(PHPUnitSetList::PHPUNIT_YIELD_DATA_PROVIDER); $config->parallel(); $config->paths([__DIR__ . '/src', __DIR__ . '/tests']); + $config->skip([__DIR__ . '/src/IndefiniteLengthMapObject.php', __DIR__ . '/src/MapObject.php']); $config->phpVersion(PhpVersion::PHP_80); $config->importNames(); $config->importShortClasses(); diff --git a/src/ByteStringObject.php b/src/ByteStringObject.php index 8f091cc..b7bb01f 100644 --- a/src/ByteStringObject.php +++ b/src/ByteStringObject.php @@ -4,6 +4,9 @@ namespace CBOR; +/** + * @see \CBOR\Test\ByteStringObjectTest + */ final class ByteStringObject extends AbstractCBORObject implements Normalizable { private const MAJOR_TYPE = self::MAJOR_TYPE_BYTE_STRING; diff --git a/src/Decoder.php b/src/Decoder.php index 2cc92c6..2b5b7d5 100644 --- a/src/Decoder.php +++ b/src/Decoder.php @@ -234,6 +234,6 @@ private function generateOtherObjectManager(): OtherObjectManagerInterface ->add(HalfPrecisionFloatObject::class) ->add(SinglePrecisionFloatObject::class) ->add(DoublePrecisionFloatObject::class) - ; + ; } } diff --git a/src/IndefiniteLengthByteStringObject.php b/src/IndefiniteLengthByteStringObject.php index 38b2ed2..ebe97c1 100644 --- a/src/IndefiniteLengthByteStringObject.php +++ b/src/IndefiniteLengthByteStringObject.php @@ -4,6 +4,9 @@ namespace CBOR; +/** + * @see \CBOR\Test\IndefiniteLengthByteStringObjectTest + */ final class IndefiniteLengthByteStringObject extends AbstractCBORObject implements Normalizable { private const MAJOR_TYPE = self::MAJOR_TYPE_BYTE_STRING; diff --git a/src/IndefiniteLengthTextStringObject.php b/src/IndefiniteLengthTextStringObject.php index 3ef2d22..bc3a15d 100644 --- a/src/IndefiniteLengthTextStringObject.php +++ b/src/IndefiniteLengthTextStringObject.php @@ -4,6 +4,9 @@ namespace CBOR; +/** + * @see \CBOR\Test\IndefiniteLengthTextStringObjectTest + */ final class IndefiniteLengthTextStringObject extends AbstractCBORObject implements Normalizable { private const MAJOR_TYPE = self::MAJOR_TYPE_TEXT_STRING; diff --git a/src/ListObject.php b/src/ListObject.php index d636a8f..940200c 100644 --- a/src/ListObject.php +++ b/src/ListObject.php @@ -16,6 +16,7 @@ /** * @phpstan-implements ArrayAccess * @phpstan-implements IteratorAggregate + * @see \CBOR\Test\ListObjectTest */ class ListObject extends AbstractCBORObject implements Countable, IteratorAggregate, Normalizable, ArrayAccess { diff --git a/src/OtherObject/SimpleObject.php b/src/OtherObject/SimpleObject.php index a47379c..03b6d05 100644 --- a/src/OtherObject/SimpleObject.php +++ b/src/OtherObject/SimpleObject.php @@ -7,6 +7,7 @@ use CBOR\Normalizable; use CBOR\OtherObject as Base; use CBOR\Utils; +use function chr; use InvalidArgumentException; use function ord; @@ -17,6 +18,28 @@ public static function supportedAdditionalInformation(): array return array_merge(range(0, 19), [24]); } + public static function create(int $value): self|FalseObject|TrueObject|NullObject|UndefinedObject + { + switch (true) { + case $value >= 0 && $value <= 19: + return new self($value, null); + case $value === 20: + return FalseObject::create(); + case $value === 21: + return TrueObject::create(); + case $value === 22: + return NullObject::create(); + case $value === 23: + return UndefinedObject::create(); + case $value <= 31: + throw new InvalidArgumentException('Invalid simple value. Shall be between 32 and 255.'); + case $value <= 255: + return new self(24, chr($value)); + default: + throw new InvalidArgumentException('The value is not a valid simple value.'); + } + } + public static function createFromLoadedData(int $additionalInformation, ?string $data): Base { if ($additionalInformation === 24) { diff --git a/src/Tag/DatetimeTag.php b/src/Tag/DatetimeTag.php index 2bb0985..ff556ae 100644 --- a/src/Tag/DatetimeTag.php +++ b/src/Tag/DatetimeTag.php @@ -14,6 +14,9 @@ use DateTimeInterface; use InvalidArgumentException; +/** + * @see \CBOR\Test\Tag\DatetimeTagTest + */ final class DatetimeTag extends Tag implements Normalizable { public function __construct(int $additionalInformation, ?string $data, CBORObject $object) diff --git a/src/Tag/MimeTag.php b/src/Tag/MimeTag.php index a7dc41a..60be796 100644 --- a/src/Tag/MimeTag.php +++ b/src/Tag/MimeTag.php @@ -11,6 +11,9 @@ use CBOR\TextStringObject; use InvalidArgumentException; +/** + * @see \CBOR\Test\Tag\MimeTagTest + */ final class MimeTag extends Tag implements Normalizable { public function __construct(int $additionalInformation, ?string $data, CBORObject $object) diff --git a/src/Tag/TimestampTag.php b/src/Tag/TimestampTag.php index c9a725c..afdec9f 100644 --- a/src/Tag/TimestampTag.php +++ b/src/Tag/TimestampTag.php @@ -53,7 +53,7 @@ public function normalize(): DateTimeInterface case $object instanceof NegativeIntegerObject: $formatted = DateTimeImmutable::createFromFormat('U', $object->normalize()); - break; + break; case $object instanceof HalfPrecisionFloatObject: case $object instanceof SinglePrecisionFloatObject: case $object instanceof DoublePrecisionFloatObject: diff --git a/src/TextStringObject.php b/src/TextStringObject.php index c14c460..a0ca87a 100644 --- a/src/TextStringObject.php +++ b/src/TextStringObject.php @@ -4,6 +4,9 @@ namespace CBOR; +/** + * @see \CBOR\Test\TextStringObjectTest + */ final class TextStringObject extends AbstractCBORObject implements Normalizable { private const MAJOR_TYPE = self::MAJOR_TYPE_TEXT_STRING; diff --git a/tests/ByteStringObjectTest.php b/tests/ByteStringObjectTest.php index 3577608..a7727d0 100644 --- a/tests/ByteStringObjectTest.php +++ b/tests/ByteStringObjectTest.php @@ -7,16 +7,16 @@ use CBOR\ByteStringObject; use CBOR\CBORObject; use CBOR\StringStream; +use PHPUnit\Framework\Attributes\DataProvider; +use PHPUnit\Framework\Attributes\Test; /** * @internal */ final class ByteStringObjectTest extends CBORTestCase { - /** - * @test - * @dataProvider getData - */ + #[DataProvider('getData')] + #[Test] public function aByteStringObjectCanBeCreated( string $string, int $expectedAdditionalInformation, @@ -47,7 +47,7 @@ public function aByteStringObjectCanBeCreated( static::assertSame($string, $decoded->normalize()); } - public function getData(): array + public static function getData(): array { return [ ['Hello', 5, 5, '4548656c6c6f'], diff --git a/tests/DoublePrecisionFloat.php b/tests/DoublePrecisionFloat.php index 3259875..3dcf68f 100644 --- a/tests/DoublePrecisionFloat.php +++ b/tests/DoublePrecisionFloat.php @@ -5,15 +5,14 @@ namespace CBOR\Test; use CBOR\OtherObject\DoublePrecisionFloatObject; +use PHPUnit\Framework\Attributes\Test; /** * @internal */ final class DoublePrecisionFloat extends CBORTestCase { - /** - * @test - */ + #[Test] public function aDoublePrecisionObjectCanBeCreated(): void { $obj = DoublePrecisionFloatObject::create(hex2bin('3fd5555555555555')); diff --git a/tests/FloatTest.php b/tests/FloatTest.php index c71fae0..ee8b035 100644 --- a/tests/FloatTest.php +++ b/tests/FloatTest.php @@ -5,16 +5,16 @@ namespace CBOR\Test; use CBOR\StringStream; +use PHPUnit\Framework\Attributes\DataProvider; +use PHPUnit\Framework\Attributes\Test; /** * @internal */ final class FloatTest extends CBORTestCase { - /** - * @test - * @dataProvider getDataSet - */ + #[DataProvider('getDataSet')] + #[Test] public function aFloatCanBeParsed(string $data): void { $stream = StringStream::create(hex2bin($data)); @@ -25,7 +25,7 @@ public function aFloatCanBeParsed(string $data): void static::assertSame($data, bin2hex((string) $object)); } - public function getDataSet(): array + public static function getDataSet(): array { return [ ['f90000'], ['f98000'], ['f93c00'], ['fb3ff199999999999a'], ['f93e00'], [ diff --git a/tests/GlobalTest.php b/tests/GlobalTest.php index 167a850..72d8ca4 100644 --- a/tests/GlobalTest.php +++ b/tests/GlobalTest.php @@ -5,16 +5,16 @@ namespace CBOR\Test; use CBOR\StringStream; +use PHPUnit\Framework\Attributes\DataProvider; +use PHPUnit\Framework\Attributes\Test; /** * @internal */ final class GlobalTest extends CBORTestCase { - /** - * @test - * @dataProvider getDataSet - */ + #[DataProvider('getDataSet')] + #[Test] public function aSignedIntegerCanBeParsed(string $data): void { $stream = StringStream::create(hex2bin($data)); @@ -24,7 +24,7 @@ public function aSignedIntegerCanBeParsed(string $data): void static::assertSame($data, bin2hex((string) $object)); } - public function getDataSet(): array + public static function getDataSet(): array { return [ [ diff --git a/tests/IndefiniteLengthByteStringObjectTest.php b/tests/IndefiniteLengthByteStringObjectTest.php index 19c01b8..0b9c12c 100644 --- a/tests/IndefiniteLengthByteStringObjectTest.php +++ b/tests/IndefiniteLengthByteStringObjectTest.php @@ -7,16 +7,16 @@ use CBOR\CBORObject; use CBOR\IndefiniteLengthByteStringObject; use CBOR\StringStream; +use PHPUnit\Framework\Attributes\DataProvider; +use PHPUnit\Framework\Attributes\Test; /** * @internal */ final class IndefiniteLengthByteStringObjectTest extends CBORTestCase { - /** - * @test - * @dataProvider getData - */ + #[DataProvider('getData')] + #[Test] public function aIndefiniteLengthByteStringObjectCanBeCreated( array $chunks, int $expectedLength, @@ -50,7 +50,7 @@ public function aIndefiniteLengthByteStringObjectCanBeCreated( static::assertSame($expectedValue, $decoded->normalize()); } - public function getData(): array + public static function getData(): array { return [ [['He', 'll', 'o'], 5, 'Hello', '5f424865426c6c416fff'], diff --git a/tests/IndefiniteLengthTextStringObjectTest.php b/tests/IndefiniteLengthTextStringObjectTest.php index c8eff8b..15f74ea 100644 --- a/tests/IndefiniteLengthTextStringObjectTest.php +++ b/tests/IndefiniteLengthTextStringObjectTest.php @@ -8,16 +8,16 @@ use CBOR\IndefiniteLengthTextStringObject; use CBOR\StringStream; use CBOR\TextStringObject; +use PHPUnit\Framework\Attributes\DataProvider; +use PHPUnit\Framework\Attributes\Test; /** * @internal */ final class IndefiniteLengthTextStringObjectTest extends CBORTestCase { - /** - * @test - * @dataProvider getData - */ + #[DataProvider('getData')] + #[Test] public function aIndefiniteLengthTextStringObjectCanBeCreated( array $chunks, int $expectedLength, @@ -51,7 +51,7 @@ public function aIndefiniteLengthTextStringObjectCanBeCreated( static::assertSame($expectedValue, $decoded->normalize()); } - public function getData(): array + public static function getData(): array { return [ [['He', 'll', 'o'], 5, 'Hello', '7f624865626c6c616fff'], diff --git a/tests/InvalidTypeTest.php b/tests/InvalidTypeTest.php index d2269a9..494a095 100644 --- a/tests/InvalidTypeTest.php +++ b/tests/InvalidTypeTest.php @@ -7,6 +7,8 @@ use Brick\Math\Exception\IntegerOverflowException; use CBOR\StringStream; use InvalidArgumentException; +use PHPUnit\Framework\Attributes\DataProvider; +use PHPUnit\Framework\Attributes\Test; use RuntimeException; /** @@ -14,10 +16,8 @@ */ final class InvalidTypeTest extends CBORTestCase { - /** - * @test - * @dataProvider getInvalidDataItems - */ + #[DataProvider('getInvalidDataItems')] + #[Test] public function invalidData(string $item, string $class, string $expectedError): void { $this->expectException($class); @@ -32,7 +32,7 @@ public function invalidData(string $item, string $class, string $expectedError): /** * @see https://datatracker.ietf.org/doc/html/rfc8949#appendix-F.1 */ - public function getInvalidDataItems(): array + public static function getInvalidDataItems(): array { return [ [ diff --git a/tests/ListObjectTest.php b/tests/ListObjectTest.php index a30d637..1bdb7b1 100644 --- a/tests/ListObjectTest.php +++ b/tests/ListObjectTest.php @@ -8,15 +8,14 @@ use CBOR\ListObject; use CBOR\TextStringObject; use CBOR\UnsignedIntegerObject; +use PHPUnit\Framework\Attributes\Test; /** * @internal */ final class ListObjectTest extends CBORTestCase { - /** - * @test - */ + #[Test] public function aListActsAsAnArray(): void { $object1 = ListObject::create() @@ -41,17 +40,15 @@ public function aListActsAsAnArray(): void static::assertSame(['Hello', 'World', '3'], $object2->normalize()); static::assertSame($object1->normalize(), $object2->normalize()); static::assertSame((string) $object1, (string) $object2); - static::assertTrue(isset($object2[0])); - static::assertTrue(isset($object2[1])); - static::assertTrue(isset($object2[2])); + static::assertArrayHasKey(0, $object2); + static::assertArrayHasKey(1, $object2); + static::assertArrayHasKey(2, $object2); static::assertSame($object2[0]->normalize(), 'Hello'); static::assertSame($object2[1]->normalize(), 'World'); static::assertSame($object2[2]->normalize(), '3'); } - /** - * @test - */ + #[Test] public function anIndefiniteLengthListActsAsAnArray(): void { $object1 = IndefiniteLengthListObject::create() @@ -76,9 +73,9 @@ public function anIndefiniteLengthListActsAsAnArray(): void static::assertSame(['Hello', 'World', '3'], $object2->normalize()); static::assertSame($object1->normalize(), $object2->normalize()); static::assertSame((string) $object1, (string) $object2); - static::assertTrue(isset($object2[0])); - static::assertTrue(isset($object2[1])); - static::assertTrue(isset($object2[2])); + static::assertArrayHasKey(0, $object2); + static::assertArrayHasKey(1, $object2); + static::assertArrayHasKey(2, $object2); static::assertSame($object2[0]->normalize(), 'Hello'); static::assertSame($object2[1]->normalize(), 'World'); static::assertSame($object2[2]->normalize(), '3'); diff --git a/tests/MapObjectTest.php b/tests/MapObjectTest.php index 203468e..527b694 100644 --- a/tests/MapObjectTest.php +++ b/tests/MapObjectTest.php @@ -11,15 +11,14 @@ use CBOR\NegativeIntegerObject; use CBOR\TextStringObject; use CBOR\UnsignedIntegerObject; +use PHPUnit\Framework\Attributes\Test; /** * @internal */ final class MapObjectTest extends CBORTestCase { - /** - * @test - */ + #[Test] public function aMapActsAsAnArray(): void { $object1 = MapObject::create() @@ -49,19 +48,17 @@ public function aMapActsAsAnArray(): void ], $object2->normalize()); static::assertSame($object1->normalize(), $object2->normalize()); static::assertSame((string) $object1, (string) $object2); - static::assertTrue(isset($object2[10])); - static::assertTrue(isset($object2[-150])); - static::assertTrue(isset($object2['AZERTY'])); - static::assertTrue(isset($object2['Test'])); + static::assertArrayHasKey(10, $object2); + static::assertArrayHasKey(-150, $object2); + static::assertArrayHasKey('AZERTY', $object2); + static::assertArrayHasKey('Test', $object2); static::assertSame($object2[10]->normalize(), 'Hello'); static::assertSame($object2[-150]->normalize(), 'World'); static::assertSame($object2['AZERTY']->normalize(), '1'); static::assertSame($object2['Test']->normalize(), '3'); } - /** - * @test - */ + #[Test] public function anIndefiniteLengthMapActsAsAnArray(): void { $object1 = IndefiniteLengthMapObject::create() @@ -91,10 +88,10 @@ public function anIndefiniteLengthMapActsAsAnArray(): void ], $object2->normalize()); static::assertSame($object1->normalize(), $object2->normalize()); static::assertSame((string) $object1, (string) $object2); - static::assertTrue(isset($object2[10])); - static::assertTrue(isset($object2[-150])); - static::assertTrue(isset($object2['AZERTY'])); - static::assertTrue(isset($object2['Test'])); + static::assertArrayHasKey(10, $object2); + static::assertArrayHasKey(-150, $object2); + static::assertArrayHasKey('AZERTY', $object2); + static::assertArrayHasKey('Test', $object2); static::assertSame($object2[10]->normalize(), 'Hello'); static::assertSame($object2[-150]->normalize(), 'World'); static::assertSame($object2['AZERTY']->normalize(), '1'); diff --git a/tests/OtherObject/All.php b/tests/OtherObject/AllTest.php similarity index 59% rename from tests/OtherObject/All.php rename to tests/OtherObject/AllTest.php index 238fa35..031b2d9 100644 --- a/tests/OtherObject/All.php +++ b/tests/OtherObject/AllTest.php @@ -4,6 +4,7 @@ namespace CBOR\Test\OtherObject; +use Brick\Math\BigInteger; use CBOR\CBORObject; use CBOR\Normalizable; use CBOR\OtherObject\BreakObject; @@ -21,16 +22,16 @@ use const INF; use InvalidArgumentException; use const M_PI; +use PHPUnit\Framework\Attributes\DataProvider; +use PHPUnit\Framework\Attributes\Test; use const STR_PAD_LEFT; /** * @internal */ -final class All extends CBORTestCase +final class AllTest extends CBORTestCase { - /** - * @test - */ + #[Test] public function createValidFalseObject(): void { $object = FalseObject::create(); @@ -50,9 +51,7 @@ public function createValidFalseObject(): void static::assertFalse($decoded->normalize()); } - /** - * @test - */ + #[Test] public function createValidTrueObject(): void { $object = TrueObject::create(); @@ -71,9 +70,7 @@ public function createValidTrueObject(): void static::assertTrue($decoded->normalize()); } - /** - * @test - */ + #[Test] public function createValidNullObject(): void { $object = NullObject::create(); @@ -92,9 +89,7 @@ public function createValidNullObject(): void static::assertNull($decoded->normalize()); } - /** - * @test - */ + #[Test] public function createValidUndefinedObject(): void { $object = UndefinedObject::create(); @@ -113,9 +108,7 @@ public function createValidUndefinedObject(): void static::assertNotInstanceOf(Normalizable::class, $decoded); } - /** - * @test - */ + #[Test] public function createValidBreakObject(): void { $object = BreakObject::create(); @@ -125,10 +118,40 @@ public function createValidBreakObject(): void static::assertNotInstanceOf(Normalizable::class, $object); } - /** - * @test - * @dataProvider getSimpleObjectWithoutContent - */ + #[Test] + public function simpleObjectOf20IsFalseObject(): void + { + $object = SimpleObject::create(20); + + static::assertInstanceOf(FalseObject::class, $object); + } + + #[Test] + public function simpleObjectOf21IsTrueObject(): void + { + $object = SimpleObject::create(21); + + static::assertInstanceOf(TrueObject::class, $object); + } + + #[Test] + public function simpleObjectOf22IsNullObject(): void + { + $object = SimpleObject::create(22); + + static::assertInstanceOf(NullObject::class, $object); + } + + #[Test] + public function simpleObjectOf23IsUndefinedObject(): void + { + $object = SimpleObject::create(23); + + static::assertInstanceOf(UndefinedObject::class, $object); + } + + #[DataProvider('getSimpleObjectWithoutContent')] + #[Test] public function createValidSimpleObjectWithoutContent(int $value): void { $object = SimpleObject::create($value); @@ -145,13 +168,11 @@ public function createValidSimpleObjectWithoutContent(int $value): void static::assertSame(CBORObject::MAJOR_TYPE_OTHER_TYPE, $decoded->getMajorType()); static::assertSame($value, $decoded->getAdditionalInformation()); static::assertNull($decoded->getContent()); - //static::assertEquals($value, $decoded->normalize()); + static::assertSame($value, $decoded->normalize()); } - /** - * @test - * @dataProvider getHalfPrecisionFloatObject - */ + #[DataProvider('getHalfPrecisionFloatObject')] + #[Test] public function createValidHalfPrecisionFloatObject(string $value, float $expected, float $delta): void { $object = HalfPrecisionFloatObject::create($value); @@ -165,10 +186,8 @@ public function createValidHalfPrecisionFloatObject(string $value, float $expect } } - /** - * @test - * @dataProvider getSinglePrecisionFloatObject - */ + #[DataProvider('getSinglePrecisionFloatObject')] + #[Test] public function createValidSinglePrecisionFloatObject(string $value, float $expected, float $delta): void { $object = SinglePrecisionFloatObject::create($value); @@ -182,10 +201,8 @@ public function createValidSinglePrecisionFloatObject(string $value, float $expe } } - /** - * @test - * @dataProvider getDoublePrecisionFloatObject - */ + #[DataProvider('getDoublePrecisionFloatObject')] + #[Test] public function createValidDoublePrecisionFloatObject(string $value, float $expected, float $delta): void { $object = DoublePrecisionFloatObject::create($value); @@ -199,10 +216,8 @@ public function createValidDoublePrecisionFloatObject(string $value, float $expe } } - /** - * @test - * @dataProvider getSimpleObjectWithContent - */ + #[DataProvider('getSimpleObjectWithContent')] + #[Test] public function createValidSimpleObjectWithContent(int $value): void { $object = SimpleObject::create($value); @@ -223,9 +238,7 @@ public function createValidSimpleObjectWithContent(int $value): void //static::assertEquals($value, $decoded->normalize()); } - /** - * @test - */ + #[Test] public function createInvalidSimpleObjectWithContent(): void { $this->expectException(InvalidArgumentException::class); @@ -234,9 +247,7 @@ public function createInvalidSimpleObjectWithContent(): void SimpleObject::createFromLoadedData(0, ' '); } - /** - * @test - */ + #[Test] public function createInvalidSimpleObjectOutOfRange(): void { $this->expectException(InvalidArgumentException::class); @@ -245,12 +256,12 @@ public function createInvalidSimpleObjectOutOfRange(): void SimpleObject::create(256); } - public function getSimpleObjectWithoutContent(): array + public static function getSimpleObjectWithoutContent(): array { return [[0], [18], [19]]; } - public function getSimpleObjectWithContent(): array + public static function getSimpleObjectWithContent(): array { return [[32], [255]]; } @@ -258,157 +269,152 @@ public function getSimpleObjectWithContent(): array /** * @see https://en.wikipedia.org/wiki/Half-precision_floating-point_format */ - public function getHalfPrecisionFloatObject(): array + public static function getHalfPrecisionFloatObject(): array { return [ - [$this->bin('0000000000000001', 2), 0.000000059604645, 0.000000000000001], - [$this->bin('0000001111111111', 2), 0.000060975552, 0.000000000001], - [$this->bin('0000010000000000', 2), 0.00006103515625, 0.00000000000001], - [$this->bin('0111101111111111', 2), 65504, 1], - [$this->bin('0011101111111111', 2), 0.99951172, 0.00000001], - [$this->bin('0011110000000000', 2), 1, 1], - [$this->bin('0011110000000001', 2), 1.00097656, 0.00000001], - [$this->bin('0011010101010101', 2), 0.333251953125, 0.000000000001], - [$this->bin('1100000000000000', 2), -1, 1], - [$this->bin('0000000000000000', 2), 0, 1], - [$this->bin('1000000000000000', 2), -0, 1], - [$this->bin('0111110000000000', 2), INF, 1], - [$this->bin('1111110000000000', 2), -INF, 1], + [self::bitsToByteString('0000000000000001', 2), 0.000000059604645, 0.000000000000001], + [self::bitsToByteString('0000001111111111', 2), 0.000060975552, 0.000000000001], + [self::bitsToByteString('0000010000000000', 2), 0.00006103515625, 0.00000000000001], + [self::bitsToByteString('0111101111111111', 2), 65504, 1], + [self::bitsToByteString('0011101111111111', 2), 0.99951172, 0.00000001], + [self::bitsToByteString('0011110000000000', 2), 1, 1], + [self::bitsToByteString('0011110000000001', 2), 1.00097656, 0.00000001], + [self::bitsToByteString('0011010101010101', 2), 0.333251953125, 0.000000000001], + [self::bitsToByteString('1100000000000000', 2), -1, 1], + [self::bitsToByteString('0000000000000000', 2), 0, 1], + [self::bitsToByteString('1000000000000000', 2), -0, 1], + [self::bitsToByteString('0111110000000000', 2), INF, 1], + [self::bitsToByteString('1111110000000000', 2), -INF, 1], ]; } /** * @see https://en.wikipedia.org/wiki/Single-precision_floating-point_format */ - public function getSinglePrecisionFloatObject(): array + public static function getSinglePrecisionFloatObject(): array { return [ - [$this->bin('00000000000000000000000000000001', 4), 2 ** -149, 10 ** -149], - [$this->bin('00000000011111111111111111111111', 4), 1.1754942107 * 10 ** -38, 10 ** -38], - [$this->bin('00000000100000000000000000000000', 4), 1.1754943508 * 10 ** -38, 10 ** -38], - [$this->bin('01111111011111111111111111111111', 4), 3.4028234664 * 10 ** 38, 10 ** 38], - [$this->bin('00111111011111111111111111111111', 4), 0.999999940395355225, 0.000000000000000001], - [$this->bin('00111111100000000000000000000000', 4), 1, 1], - [$this->bin('00111111100000000000000000000001', 4), 1.00000011920928955, 0.00000000000000001], - [$this->bin('11000000000000000000000000000000', 4), -2, 1], - [$this->bin('00000000000000000000000000000000', 4), 0, 0], - [$this->bin('10000000000000000000000000000000', 4), -0, 0], - [$this->bin('01111111100000000000000000000000', 4), INF, 0], - [$this->bin('11111111100000000000000000000000', 4), -INF, 0], - [$this->bin('01000000010010010000111111011011', 4), 3.14159274101257324, 0.00000000000000001], - [$this->bin('00111110101010101010101010101011', 4), 0.333333343267440796, 0.000000000000000001], + [self::bitsToByteString('00000000000000000000000000000001', 4), 2 ** -149, 10 ** -149], + [self::bitsToByteString('00000000011111111111111111111111', 4), 1.1754942107 * 10 ** -38, 10 ** -38], + [self::bitsToByteString('00000000100000000000000000000000', 4), 1.1754943508 * 10 ** -38, 10 ** -38], + [self::bitsToByteString('01111111011111111111111111111111', 4), 3.4028234664 * 10 ** 38, 10 ** 38], + [self::bitsToByteString('00111111011111111111111111111111', 4), 0.999999940395355225, 0.000000000000000001], + [self::bitsToByteString('00111111100000000000000000000000', 4), 1, 1], + [self::bitsToByteString('00111111100000000000000000000001', 4), 1.00000011920928955, 0.00000000000000001], + [self::bitsToByteString('11000000000000000000000000000000', 4), -2, 1], + [self::bitsToByteString('00000000000000000000000000000000', 4), 0, 0], + [self::bitsToByteString('10000000000000000000000000000000', 4), -0, 0], + [self::bitsToByteString('01111111100000000000000000000000', 4), INF, 0], + [self::bitsToByteString('11111111100000000000000000000000', 4), -INF, 0], + [self::bitsToByteString('01000000010010010000111111011011', 4), 3.14159274101257324, 0.00000000000000001], + [self::bitsToByteString('00111110101010101010101010101011', 4), 0.333333343267440796, 0.000000000000000001], ]; } /** * @see https://en.wikipedia.org/wiki/Double-precision_floating-point_format */ - public function getDoublePrecisionFloatObject(): array + public static function getDoublePrecisionFloatObject(): array { return [ - [$this->bin('0011111111110000000000000000000000000000000000000000000000000000', 8), 1, 1], + [self::bitsToByteString('0011111111110000000000000000000000000000000000000000000000000000', 8), 1, 1], [ - $this->bin('0011111111110000000000000000000000000000000000000000000000000001', 8), + self::bitsToByteString('0011111111110000000000000000000000000000000000000000000000000001', 8), 1.0000000000000002, 0.0000000000000001, ], [ - $this->bin('0011111111110000000000000000000000000000000000000000000000000010', 8), + self::bitsToByteString('0011111111110000000000000000000000000000000000000000000000000010', 8), 1.0000000000000004, 0.0000000000000001, ], [ - $this->bin('0100000000000000000000000000000000000000000000000000000000000000', 8), + self::bitsToByteString('0100000000000000000000000000000000000000000000000000000000000000', 8), 2, 0.0000000000000001, ], [ - $this->bin('1100000000000000000000000000000000000000000000000000000000000000', 8), + self::bitsToByteString('1100000000000000000000000000000000000000000000000000000000000000', 8), -2, 0.0000000000000001, ], [ - $this->bin('0100000000001000000000000000000000000000000000000000000000000000', 8), + self::bitsToByteString('0100000000001000000000000000000000000000000000000000000000000000', 8), 3, 0.0000000000000001, ], [ - $this->bin('0100000000010000000000000000000000000000000000000000000000000000', 8), + self::bitsToByteString('0100000000010000000000000000000000000000000000000000000000000000', 8), 4, 0.0000000000000001, ], [ - $this->bin('0100000000010100000000000000000000000000000000000000000000000000', 8), + self::bitsToByteString('0100000000010100000000000000000000000000000000000000000000000000', 8), 5, 0.0000000000000001, ], [ - $this->bin('0100000000011000000000000000000000000000000000000000000000000000', 8), + self::bitsToByteString('0100000000011000000000000000000000000000000000000000000000000000', 8), 6, 0.0000000000000001, ], [ - $this->bin('0100000000110111000000000000000000000000000000000000000000000000', 8), + self::bitsToByteString('0100000000110111000000000000000000000000000000000000000000000000', 8), 23, 0.0000000000000001, ], [ - $this->bin('0011111110001000000000000000000000000000000000000000000000000000', 8), + self::bitsToByteString('0011111110001000000000000000000000000000000000000000000000000000', 8), 0.01171875, 0.00000001, ], [ - $this->bin('0000000000000000000000000000000000000000000000000000000000000001', 8), + self::bitsToByteString('0000000000000000000000000000000000000000000000000000000000000001', 8), 4.9406564584124654 * 10 ** -324, - 10 ** -324, + 10 ** -323, ], [ - $this->bin('0000000000001111111111111111111111111111111111111111111111111111', 8), + self::bitsToByteString('0000000000001111111111111111111111111111111111111111111111111111', 8), 2.2250738585072009 * 10 ** -308, 10 ** -308, ], [ - $this->bin('0000000000010000000000000000000000000000000000000000000000000000', 8), + self::bitsToByteString('0000000000010000000000000000000000000000000000000000000000000000', 8), 2.2250738585072014 * 10 ** -308, 10 ** -308, ], [ - $this->bin('0111111111101111111111111111111111111111111111111111111111111111', 8), + self::bitsToByteString('0111111111101111111111111111111111111111111111111111111111111111', 8), 1.7976931348623157 * 10 ** 308, 1, ], [ - $this->bin('0000000000000000000000000000000000000000000000000000000000000000', 8), + self::bitsToByteString('0000000000000000000000000000000000000000000000000000000000000000', 8), 0, 0.0000000000000001, ], [ - $this->bin('1000000000000000000000000000000000000000000000000000000000000000', 8), + self::bitsToByteString('1000000000000000000000000000000000000000000000000000000000000000', 8), -0, 0.0000000000000001, ], - [$this->bin('0111111111110000000000000000000000000000000000000000000000000000', 8), INF, 1], - [$this->bin('1111111111110000000000000000000000000000000000000000000000000000', 8), -INF, 1], + [self::bitsToByteString('0111111111110000000000000000000000000000000000000000000000000000', 8), INF, 1], + [self::bitsToByteString('1111111111110000000000000000000000000000000000000000000000000000', 8), -INF, 1], [ - $this->bin('0011111111010101010101010101010101010101010101010101010101010101', 8), + self::bitsToByteString('0011111111010101010101010101010101010101010101010101010101010101', 8), 1 / 3, 0.0000000000000001, ], [ - $this->bin('0100000000001001001000011111101101010100010001000010110100011000', 8), + self::bitsToByteString('0100000000001001001000011111101101010100010001000010110100011000', 8), M_PI, 0.0000000000000001, ], ]; } - private function bin(string $binary, int $length): string + private static function bitsToByteString(string $data, int $length): string { - return str_pad( - hex2bin(str_pad(base_convert($binary, 2, 16), $length * 2, '0', STR_PAD_LEFT)), - $length, - '0', - STR_PAD_LEFT - ); + return str_pad(BigInteger::fromBase($data, 2)->toBytes(false), $length, "\0", STR_PAD_LEFT); } } diff --git a/tests/OtherTest.php b/tests/OtherTest.php index 3facd09..8b13b94 100644 --- a/tests/OtherTest.php +++ b/tests/OtherTest.php @@ -5,16 +5,16 @@ namespace CBOR\Test; use CBOR\StringStream; +use PHPUnit\Framework\Attributes\DataProvider; +use PHPUnit\Framework\Attributes\Test; /** * @internal */ final class OtherTest extends CBORTestCase { - /** - * @test - * @dataProvider getDataSet - */ + #[DataProvider('getDataSet')] + #[Test] public function aSignedIntegerCanBeParsed(string $data): void { $stream = StringStream::create(hex2bin($data)); @@ -24,7 +24,7 @@ public function aSignedIntegerCanBeParsed(string $data): void static::assertSame($data, bin2hex((string) $object)); } - public function getDataSet(): array + public static function getDataSet(): array { return [['f4'], ['f5'], ['f6'], ['f7'], ['f0'], ['f820'], ['f8ff']]; } diff --git a/tests/SignedIntegerTest.php b/tests/SignedIntegerTest.php index b6bd8a9..aa2319b 100644 --- a/tests/SignedIntegerTest.php +++ b/tests/SignedIntegerTest.php @@ -7,16 +7,16 @@ use CBOR\NegativeIntegerObject; use CBOR\StringStream; use InvalidArgumentException; +use PHPUnit\Framework\Attributes\DataProvider; +use PHPUnit\Framework\Attributes\Test; /** * @internal */ final class SignedIntegerTest extends CBORTestCase { - /** - * @test - * @dataProvider getValidValue - */ + #[DataProvider('getValidValue')] + #[Test] public function createOnValidValue( int $intValue, string $expectedIntValue, @@ -29,7 +29,7 @@ public function createOnValidValue( static::assertSame($expectedAdditionalInformation, $unsignedInteger->getAdditionalInformation()); } - public function getValidValue(): array + public static function getValidValue(): array { return [ [-12_345_678, '-12345678', 1, 26], @@ -40,9 +40,7 @@ public function getValidValue(): array ]; } - /** - * @test - */ + #[Test] public function ceateOnNegativeValue(): void { $this->expectException(InvalidArgumentException::class); @@ -50,9 +48,7 @@ public function ceateOnNegativeValue(): void NegativeIntegerObject::create(1); } - /** - * @test - */ + #[Test] public function createOnOutOfRangeValue(): void { $this->expectException(InvalidArgumentException::class); @@ -62,10 +58,8 @@ public function createOnOutOfRangeValue(): void NegativeIntegerObject::create(-4_294_967_297); } - /** - * @test - * @dataProvider getDataSet - */ + #[DataProvider('getDataSet')] + #[Test] public function anUnsignedIntegerCanBeEncodedAndDecoded(string $data, string $expectedNormalizedData): void { $stream = StringStream::create(hex2bin($data)); @@ -77,7 +71,7 @@ public function anUnsignedIntegerCanBeEncodedAndDecoded(string $data, string $ex static::assertSame($expectedNormalizedData, $object->normalize()); } - public function getDataSet(): array + public static function getDataSet(): array { return [ ['20', '-1'], ['29', '-10'], ['3863', '-100'], ['3903e7', '-1000'], [ diff --git a/tests/Tag/DatetimeTagTest.php b/tests/Tag/DatetimeTagTest.php index f35c069..77cb7f6 100644 --- a/tests/Tag/DatetimeTagTest.php +++ b/tests/Tag/DatetimeTagTest.php @@ -15,6 +15,8 @@ use CBOR\TextStringObject; use CBOR\UnsignedIntegerObject; use InvalidArgumentException; +use PHPUnit\Framework\Attributes\DataProvider; +use PHPUnit\Framework\Attributes\Test; use PHPUnit\Framework\TestCase; /** @@ -22,19 +24,15 @@ */ final class DatetimeTagTest extends TestCase { - /** - * @test - * @dataProvider getDatetimes - */ + #[DataProvider('getDatetimes')] + #[Test] public function createValidDatetimeTag(CBORObject $object, string $expectedTimestamp): void { $tag = DatetimeTag::create($object); static::assertSame($expectedTimestamp, $tag->normalize()->format('U.u')); } - /** - * @test - */ + #[Test] public function createInvalidDatetimeTag(): void { $this->expectException(InvalidArgumentException::class); @@ -43,27 +41,21 @@ public function createInvalidDatetimeTag(): void DatetimeTag::create(ByteStringObject::create('data')); } - /** - * @test - */ + #[Test] public function createValidTimestampTagWithUnsignedInteger(): void { $tag = TimestampTag::create(UnsignedIntegerObject::create(0)); static::assertSame('0.000000', $tag->normalize()->format('U.u')); } - /** - * @test - */ + #[Test] public function createValidTimestampTagWithNegativeInteger(): void { $tag = TimestampTag::create(NegativeIntegerObject::create(-10)); static::assertSame('-10.000000', $tag->normalize()->format('U.u')); } - /** - * @test - */ + #[Test] public function createValidTimestampTagWithHalfPrecisionFloat(): void { $tag = TimestampTag::create( @@ -72,9 +64,7 @@ public function createValidTimestampTagWithHalfPrecisionFloat(): void static::assertSame('0.333251', $tag->normalize()->format('U.u')); } - /** - * @test - */ + #[Test] public function createValidTimestampTagWithSinglePrecisionFloat(): void { $tag = TimestampTag::create( @@ -83,9 +73,7 @@ public function createValidTimestampTagWithSinglePrecisionFloat(): void static::assertSame('0.999999', $tag->normalize()->format('U.u')); } - /** - * @test - */ + #[Test] public function createValidTimestampTagWithDoublePrecisionFloat(): void { $tag = TimestampTag::create( @@ -96,7 +84,7 @@ public function createValidTimestampTagWithDoublePrecisionFloat(): void static::assertSame('3.141592', $tag->normalize()->format('U.u')); } - public function getDatetimes(): array + public static function getDatetimes(): array { $buildTestEntry = static fn (string $datetime, string $timestamp): array => [ TextStringObject::create($datetime), diff --git a/tests/Tag/EncodingTagsTest.php b/tests/Tag/EncodingTagsTest.php index 3f61ab7..622fd53 100644 --- a/tests/Tag/EncodingTagsTest.php +++ b/tests/Tag/EncodingTagsTest.php @@ -12,6 +12,7 @@ use CBOR\Tag\CBOREncodingTag; use CBOR\TextStringObject; use InvalidArgumentException; +use PHPUnit\Framework\Attributes\Test; use PHPUnit\Framework\TestCase; /** @@ -19,9 +20,7 @@ */ final class EncodingTagsTest extends TestCase { - /** - * @test - */ + #[Test] public function createValidBase16EncodingTag(): void { $tag = Base16EncodingTag::create(TextStringObject::create('Text')); @@ -31,9 +30,7 @@ public function createValidBase16EncodingTag(): void static::assertSame(CBORObject::TAG_ENCODED_BASE16, $tag->getAdditionalInformation()); } - /** - * @test - */ + #[Test] public function createValidBase64EncodingTag(): void { $tag = Base64EncodingTag::create(TextStringObject::create('Text')); @@ -43,9 +40,7 @@ public function createValidBase64EncodingTag(): void static::assertSame(CBORObject::TAG_ENCODED_BASE64, $tag->getAdditionalInformation()); } - /** - * @test - */ + #[Test] public function createValidBase64UrlEncodingTag(): void { $tag = Base64UrlEncodingTag::create(TextStringObject::create('Text')); @@ -55,9 +50,7 @@ public function createValidBase64UrlEncodingTag(): void static::assertSame(CBORObject::TAG_ENCODED_BASE64_URL, $tag->getAdditionalInformation()); } - /** - * @test - */ + #[Test] public function createValidCBOREncodingTag(): void { $tag = CBOREncodingTag::create(ByteStringObject::create('Text')); @@ -67,9 +60,7 @@ public function createValidCBOREncodingTag(): void static::assertSame(CBORObject::TAG_ENCODED_CBOR, $tag->getAdditionalInformation()); } - /** - * @test - */ + #[Test] public function createInvalidCBOREncodingTag(): void { $this->expectException(InvalidArgumentException::class); diff --git a/tests/Tag/MimeTagTest.php b/tests/Tag/MimeTagTest.php index f11af50..8c36517 100644 --- a/tests/Tag/MimeTagTest.php +++ b/tests/Tag/MimeTagTest.php @@ -9,6 +9,7 @@ use CBOR\Tag\MimeTag; use CBOR\TextStringObject; use InvalidArgumentException; +use PHPUnit\Framework\Attributes\Test; use PHPUnit\Framework\TestCase; /** @@ -16,18 +17,14 @@ */ final class MimeTagTest extends TestCase { - /** - * @test - */ + #[Test] public function createValidTagFromTextStringObject(): void { $tag = MimeTag::create(TextStringObject::create('text/plain')); static::assertSame('text/plain', $tag->normalize()); } - /** - * @test - */ + #[Test] public function createValidTagFromTIndefiniteLengthTextStringObject(): void { $tag = MimeTag::create( @@ -39,9 +36,7 @@ public function createValidTagFromTIndefiniteLengthTextStringObject(): void static::assertSame('text/plain', $tag->normalize()); } - /** - * @test - */ + #[Test] public function createInvalidTag(): void { static::expectException(InvalidArgumentException::class); diff --git a/tests/Tag/SimpleTagsTest.php b/tests/Tag/SimpleTagsTest.php index d511126..4e7bb10 100644 --- a/tests/Tag/SimpleTagsTest.php +++ b/tests/Tag/SimpleTagsTest.php @@ -12,6 +12,7 @@ use CBOR\Tag\UriTag; use CBOR\TextStringObject; use InvalidArgumentException; +use PHPUnit\Framework\Attributes\Test; use PHPUnit\Framework\TestCase; /** @@ -19,9 +20,7 @@ */ final class SimpleTagsTest extends TestCase { - /** - * @test - */ + #[Test] public function createValidUriTag(): void { $tag = UriTag::create(TextStringObject::create('Text')); @@ -32,9 +31,7 @@ public function createValidUriTag(): void static::assertSame(hex2bin(dechex(CBORObject::TAG_URI)), $tag->getData()); } - /** - * @test - */ + #[Test] public function createInvalidUriTag(): void { $this->expectException(InvalidArgumentException::class); @@ -42,9 +39,7 @@ public function createInvalidUriTag(): void UriTag::create(ByteStringObject::create('Text')); } - /** - * @test - */ + #[Test] public function createValidBase64Tag(): void { $tag = Base64Tag::create(TextStringObject::create('Text')); @@ -55,9 +50,7 @@ public function createValidBase64Tag(): void static::assertSame(hex2bin(dechex(CBORObject::TAG_BASE64)), $tag->getData()); } - /** - * @test - */ + #[Test] public function createInvalidBase64Tag(): void { $this->expectException(InvalidArgumentException::class); @@ -65,9 +58,7 @@ public function createInvalidBase64Tag(): void Base64Tag::create(ByteStringObject::create('Text')); } - /** - * @test - */ + #[Test] public function createValidBase64UrlTag(): void { $tag = Base64UrlTag::create(TextStringObject::create('Text')); @@ -78,9 +69,7 @@ public function createValidBase64UrlTag(): void static::assertSame(hex2bin(dechex(CBORObject::TAG_BASE64_URL)), $tag->getData()); } - /** - * @test - */ + #[Test] public function createInvalidBase64UrlTag(): void { $this->expectException(InvalidArgumentException::class); @@ -88,9 +77,7 @@ public function createInvalidBase64UrlTag(): void Base64UrlTag::create(ByteStringObject::create('Text')); } - /** - * @test - */ + #[Test] public function createValidCBORTag(): void { $tag = CBORTag::create(ByteStringObject::create('Text')); diff --git a/tests/TextStringObjectTest.php b/tests/TextStringObjectTest.php index 6d13158..5c93a0f 100644 --- a/tests/TextStringObjectTest.php +++ b/tests/TextStringObjectTest.php @@ -7,16 +7,16 @@ use CBOR\CBORObject; use CBOR\StringStream; use CBOR\TextStringObject; +use PHPUnit\Framework\Attributes\DataProvider; +use PHPUnit\Framework\Attributes\Test; /** * @internal */ final class TextStringObjectTest extends CBORTestCase { - /** - * @test - * @dataProvider getData - */ + #[DataProvider('getData')] + #[Test] public function aTextStringObjectCanBeCreated( string $string, int $expectedAdditionalInformation, @@ -47,7 +47,7 @@ public function aTextStringObjectCanBeCreated( static::assertSame($string, $decoded->normalize()); } - public function getData(): array + public static function getData(): array { return [ ['Hello', 5, 5, '6548656c6c6f'], diff --git a/tests/UnsignedIntegerTest.php b/tests/UnsignedIntegerTest.php index 523a96c..533d7d1 100644 --- a/tests/UnsignedIntegerTest.php +++ b/tests/UnsignedIntegerTest.php @@ -7,16 +7,16 @@ use CBOR\StringStream; use CBOR\UnsignedIntegerObject; use InvalidArgumentException; +use PHPUnit\Framework\Attributes\DataProvider; +use PHPUnit\Framework\Attributes\Test; /** * @internal */ final class UnsignedIntegerTest extends CBORTestCase { - /** - * @test - * @dataProvider getValidValue - */ + #[DataProvider('getValidValue')] + #[Test] public function createOnValidValue( int $intValue, string $expectedIntValue, @@ -29,14 +29,12 @@ public function createOnValidValue( static::assertSame($expectedAdditionalInformation, $unsignedInteger->getAdditionalInformation()); } - public function getValidValue(): array + public static function getValidValue(): array { return [[12_345_678, '12345678', 0, 26], [255, '255', 0, 25], [254, '254', 0, 24], [18, '18', 0, 18]]; } - /** - * @test - */ + #[Test] public function createOnNegativeValue(): void { $this->expectException(InvalidArgumentException::class); @@ -44,9 +42,7 @@ public function createOnNegativeValue(): void UnsignedIntegerObject::create(-1); } - /** - * @test - */ + #[Test] public function createOnOutOfRangeValue(): void { $this->expectException(InvalidArgumentException::class); @@ -56,10 +52,8 @@ public function createOnOutOfRangeValue(): void UnsignedIntegerObject::create(4_294_967_296); } - /** - * @test - * @dataProvider getDataSet - */ + #[DataProvider('getDataSet')] + #[Test] public function anUnsignedIntegerCanBeParsed(string $data, string $expectedNormalizedData): void { $stream = StringStream::create(hex2bin($data)); @@ -70,7 +64,7 @@ public function anUnsignedIntegerCanBeParsed(string $data, string $expectedNorma static::assertSame($expectedNormalizedData, $object->normalize()); } - public function getDataSet(): array + public static function getDataSet(): array { return [ ['00', '0'], ['01', '1'], ['0a', '10'], ['17', '23'], [ diff --git a/tests/VectorTest.php b/tests/VectorTest.php index 367faff..3846717 100644 --- a/tests/VectorTest.php +++ b/tests/VectorTest.php @@ -6,16 +6,16 @@ use CBOR\StringStream; use const JSON_THROW_ON_ERROR; +use PHPUnit\Framework\Attributes\DataProvider; +use PHPUnit\Framework\Attributes\Test; /** * @internal */ final class VectorTest extends CBORTestCase { - /** - * @test - * @dataProvider getVectors - */ + #[DataProvider('getVectors')] + #[Test] public function createOnValidValue(string $cbor, string $hex): void { $stream = StringStream::create(base64_decode($cbor, true)); @@ -26,7 +26,7 @@ public function createOnValidValue(string $cbor, string $hex): void static::assertSame(hex2bin($hex), (string) $result); } - public function getVectors(): array + public static function getVectors(): array { return json_decode(file_get_contents(__DIR__ . '/vectors.json'), true, 512, JSON_THROW_ON_ERROR); } diff --git a/tests/vectors.json b/tests/vectors.json index 16ac046..1566e86 100644 --- a/tests/vectors.json +++ b/tests/vectors.json @@ -627,4 +627,4 @@ "Amt": -2 } } -] \ No newline at end of file +]