Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 30 additions & 0 deletions .ddev/commands/web/infection
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
#!/usr/bin/env bash

set -euo pipefail

## Description: Run Infection mutation testing for the MageForge module
## Usage: infection [infection-options]
## Example: ddev infection
## Example: ddev infection --show-mutations
## Example: ddev infection --filter=src/Service/Hyva/

cd /var/www/html

if [[ ! -x vendor/bin/infection ]]; then
echo "infection not found. Installing module dev dependencies..."
composer install --no-interaction
fi

if ! php -m | grep -qi '^pcov$'; then
echo "PCOV extension not loaded. Run 'ddev restart' to rebuild the web image" >&2
echo "(.ddev/web-build/Dockerfile.pcov installs it)." >&2
exit 1
fi

echo "Mutation report: reports/infection/infection.html"
# The initial PHPUnit run needs PCOV for coverage (globally off, see
# .ddev/php/pcov.ini); opcache.jit=off avoids the JIT warning PCOV triggers.
exec vendor/bin/infection \
Comment thread
Morgy93 marked this conversation as resolved.
--threads=max \
--initial-tests-php-options="-d pcov.enabled=1 -d opcache.jit=off -d opcache.jit_buffer_size=0" \
"$@"
32 changes: 30 additions & 2 deletions .ddev/commands/web/phpunit
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,12 @@
set -euo pipefail

## Description: Run PHPUnit tests for the MageForge module
## Usage: phpunit [options]
## Usage: phpunit [--coverage] [phpunit-options]
## Example: ddev phpunit
## Example: ddev phpunit --testdox
## Example: ddev phpunit tests/Unit/Service/Hyva/
## Example: ddev phpunit --coverage
## Example: ddev phpunit --coverage tests/Unit/Service/Hyva/

cd /var/www/html

Expand All @@ -15,4 +17,30 @@ if [[ ! -x vendor/bin/phpunit ]]; then
composer install --no-interaction
fi

vendor/bin/phpunit "$@"
coverage=false
args=()
for arg in "$@"; do
if [[ ${arg} == "--coverage" ]]; then
coverage=true
else
args+=("${arg}")
fi
done

if [[ ${coverage} == true ]]; then
if ! php -m | grep -qi '^pcov$'; then
echo "PCOV extension not loaded. Run 'ddev restart' to rebuild the web image" >&2
echo "(.ddev/web-build/Dockerfile.pcov installs it)." >&2
exit 1
fi
echo "Coverage reports: reports/coverage/index.html (HTML), reports/clover.xml (Clover)"
# pcov.enabled=1: opt in per-run (globally off, see .ddev/php/pcov.ini).
# opcache.jit=off: avoid the "JIT is incompatible" warning PCOV would trigger.
exec php -d pcov.enabled=1 -d opcache.jit=off -d opcache.jit_buffer_size=0 vendor/bin/phpunit \
Comment thread
Morgy93 marked this conversation as resolved.
--coverage-text \
--coverage-html reports/coverage \
--coverage-clover reports/clover.xml \
"${args[@]}"
fi

exec vendor/bin/phpunit "${args[@]}"
4 changes: 4 additions & 0 deletions .ddev/php/pcov.ini
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
; PCOV stays disabled by default: its zend_execute_ex hook forces opcache to
; disable JIT and print a warning on every PHP invocation.
; `ddev phpunit --coverage` enables it per-run via -d pcov.enabled=1.
pcov.enabled=0
3 changes: 3 additions & 0 deletions .ddev/web-build/Dockerfile.pcov
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# PCOV provides fast code coverage for PHPUnit (used by `ddev phpunit --coverage`).
# It is disabled by default via .ddev/php/pcov.ini and enabled per-run.
RUN sudo apt-get update && sudo apt-get install -y -o Dpkg::Options::="--force-confold" --no-install-recommends --no-install-suggests "php${DDEV_PHP_VERSION}-pcov"
102 changes: 95 additions & 7 deletions .github/workflows/phpunit.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,33 +5,121 @@ on: [pull_request]
permissions:
contents: read

env:
PHP_VERSION: "8.4"

jobs:
phpunit:
name: Unit Tests
name: Unit Tests (PHP ${{ matrix.php-version }})
runs-on: ubuntu-latest

strategy:
fail-fast: false
matrix:
php-version: ["8.3", "8.4"]
include:
- php-version: "8.4"
coverage: true

Comment thread
Morgy93 marked this conversation as resolved.
steps:
- name: Checkout code
uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4.3.1

- name: Set up PHP
uses: shivammathur/setup-php@accd6127cb78bee3e8082180cb391013d204ef9f # v2
with:
php-version: ${{ env.PHP_VERSION }}
php-version: ${{ matrix.php-version }}
tools: composer:v2
coverage: ${{ matrix.coverage && 'pcov' || 'none' }}

- name: Cache Composer packages
uses: actions/cache@0057852bfaa89a56745cba8c7296529d2fc39830 # v4.3.0
with:
path: ~/.composer/cache/files
key: ${{ runner.os }}-composer-phpunit-${{ hashFiles('composer.json') }}
restore-keys: ${{ runner.os }}-composer-phpunit
key: ${{ runner.os }}-composer-phpunit-${{ matrix.php-version }}-${{ hashFiles('composer.json') }}
restore-keys: ${{ runner.os }}-composer-phpunit-${{ matrix.php-version }}

- name: Install dev dependencies
run: composer install --no-interaction --no-progress

- name: Run PHPUnit
if: ${{ !matrix.coverage }}
run: vendor/bin/phpunit

- name: Run PHPUnit with coverage
if: ${{ matrix.coverage }}
# mkdir: the text report is written with a bare file_put_contents and
# relies on the Clover/HTML writers having created reports/ first.
run: |
mkdir -p reports
vendor/bin/phpunit \
--coverage-text=reports/coverage.txt \
--coverage-html reports/coverage \
--coverage-clover reports/clover.xml

- name: Publish coverage summary
if: ${{ matrix.coverage && always() }}
run: |
if [[ -f reports/coverage.txt ]]; then
{
echo '## Code Coverage'
echo '```'
cat reports/coverage.txt
echo '```'
} >> "$GITHUB_STEP_SUMMARY"
fi

- name: Upload coverage report
if: ${{ matrix.coverage && always() }}
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
with:
name: coverage-report
path: |
reports/coverage
reports/clover.xml
if-no-files-found: ignore

mutation:
name: Mutation Tests (Infection)
runs-on: ubuntu-latest

steps:
- name: Checkout code
uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4.3.1

- name: Set up PHP
uses: shivammathur/setup-php@accd6127cb78bee3e8082180cb391013d204ef9f # v2
with:
php-version: "8.4"
tools: composer:v2
coverage: pcov

- name: Cache Composer packages
uses: actions/cache@0057852bfaa89a56745cba8c7296529d2fc39830 # v4.3.0
with:
path: ~/.composer/cache/files
key: ${{ runner.os }}-composer-phpunit-8.4-${{ hashFiles('composer.json') }}
restore-keys: ${{ runner.os }}-composer-phpunit-8.4

- name: Install dev dependencies
run: composer install --no-interaction --no-progress

- name: Run Infection
run: vendor/bin/infection --threads=max --logger-github --no-progress

Comment thread
Morgy93 marked this conversation as resolved.
- name: Publish mutation summary
if: always()
run: |
if [[ -f reports/infection/summary.log ]]; then
{
echo '## Mutation Testing'
echo '```'
cat reports/infection/summary.log
echo '```'
} >> "$GITHUB_STEP_SUMMARY"
fi

- name: Upload mutation report
if: always()
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
with:
name: mutation-report
path: reports/infection
if-no-files-found: ignore
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@

# PHPUnit
/.phpunit.cache/
/reports/

.vscode
/magento/
Expand Down
6 changes: 6 additions & 0 deletions .trunk/trunk.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,12 @@ lint:
- linters: [checkov]
paths:
- .ddev/**
# DDEV web-build files are Dockerfile *fragments* concatenated into DDEV's
# generated Dockerfile: they have no FROM, and sudo is the documented DDEV
# mechanism since the build runs as the non-root web user.
- linters: [hadolint]
paths:
- .ddev/web-build/**
enabled:
- pinact@4.1.0
- svgo@4.0.1
Expand Down
7 changes: 6 additions & 1 deletion composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
},
"require-dev": {
"carthage-software/mago": "^1.30",
"infection/infection": "^0.34.0",
"magento/magento-coding-standard": "^40",
"phpunit/phpunit": "^11.0"
},
Expand All @@ -37,6 +38,7 @@
"sort-packages": true,
"allow-plugins": {
"dealerdirect/phpcodesniffer-composer-installer": true,
"infection/extension-installer": true,
"magento/composer-dependency-version-audit-plugin": true
}
},
Expand All @@ -45,6 +47,9 @@
"fmt": "mago fmt",
"fmt:check": "mago fmt --dry-run",
"phpcs": "phpcs -p -s",
"phpcbf": "phpcbf -p"
"phpcbf": "phpcbf -p",
"test": "phpunit",
"test:coverage": "phpunit --coverage-text --coverage-html reports/coverage --coverage-clover reports/clover.xml",
"test:mutation": "infection --threads=max --initial-tests-php-options='-d pcov.enabled=1'"
Comment thread
Morgy93 marked this conversation as resolved.
}
}
16 changes: 16 additions & 0 deletions infection.json5
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
{
"$schema": "vendor/infection/infection/resources/schema.json",
"source": {
"directories": ["src"],
"excludes": ["registration.php"],
Comment thread
Morgy93 marked this conversation as resolved.
},
Comment thread
Morgy93 marked this conversation as resolved.
"timeout": 10,
"logs": {
"text": "reports/infection/infection.log",
"html": "reports/infection/infection.html",
"summary": "reports/infection/summary.log",
},
"mutators": {
"@default": true,
},
}
18 changes: 16 additions & 2 deletions phpunit.xml.dist
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,29 @@
xsi:noNamespaceSchemaLocation="vendor/phpunit/phpunit/phpunit.xsd"
bootstrap="vendor/autoload.php"
colors="true"
cacheDirectory=".phpunit.cache">
cacheDirectory=".phpunit.cache"
executionOrder="random"
failOnRisky="true"
failOnWarning="true"
failOnEmptyTestSuite="true"
beStrictAboutOutputDuringTests="true"
beStrictAboutChangesToGlobalState="true"
displayDetailsOnPhpunitDeprecations="true"
displayDetailsOnTestsThatTriggerDeprecations="true"
Comment thread
Morgy93 marked this conversation as resolved.
displayDetailsOnTestsThatTriggerErrors="true"
displayDetailsOnTestsThatTriggerNotices="true"
displayDetailsOnTestsThatTriggerWarnings="true">
<testsuites>
<testsuite name="Unit">
<directory>tests/Unit</directory>
</testsuite>
</testsuites>
<source>
<source ignoreIndirectDeprecations="true">
<include>
<directory>src</directory>
</include>
<exclude>
<file>src/registration.php</file>
</exclude>
</source>
</phpunit>
Loading