From 1e85d9a53bf6312a5eec4ffd5dea7e73e44d8f82 Mon Sep 17 00:00:00 2001
From: Antonio Mangiacapra <11173091+antonioeatgoat@users.noreply.github.com>
Date: Fri, 25 Aug 2023 12:55:22 +0200
Subject: [PATCH 1/8] Update dependencies
---
composer.json | 7 +++----
phpcs.xml | 10 ++++++----
tests/cases/FixturesTest.php | 1 +
tests/src/FixtureContentParser.php | 4 ++++
4 files changed, 14 insertions(+), 8 deletions(-)
diff --git a/composer.json b/composer.json
index ff6f4fa..7644e18 100644
--- a/composer.json
+++ b/composer.json
@@ -29,11 +29,10 @@
],
"minimum-stability": "stable",
"require": {
- "php": ">=7",
+ "php": ">=7.4",
"squizlabs/php_codesniffer": "^3.6.0",
- "dealerdirect/phpcodesniffer-composer-installer": "~0.7.0",
- "wp-coding-standards/wpcs": "^2.3",
- "automattic/vipwpcs": "^2.2",
+ "dealerdirect/phpcodesniffer-composer-installer": "~1.0.0",
+ "automattic/vipwpcs": "dev-3.0/updates-for-wpcs-3.0",
"phpcompatibility/php-compatibility": "^9.3.5",
"automattic/phpcs-neutron-standard": "^1.6.0"
},
diff --git a/phpcs.xml b/phpcs.xml
index 8a81c7a..dec7c58 100644
--- a/phpcs.xml
+++ b/phpcs.xml
@@ -60,9 +60,7 @@
Curated list of WordPress specific rules.
See https://github.com/WordPress-Coding-Standards/WordPress-Coding-Standards
-->
-
-
-
+
@@ -98,7 +96,6 @@
-
@@ -152,6 +149,8 @@
Generic
-->
+
+
@@ -161,6 +160,7 @@
+
@@ -173,6 +173,8 @@
+
+
-
-
+
-
-
-
-
-
- warning
-
-
- warning
-
-
- warning
-
-
- warning
-
-
- warning
-
-
- warning
-
-
- warning
-
diff --git a/phpunit.xml.dist b/phpunit.xml.dist
index 76b6d6e..d997102 100644
--- a/phpunit.xml.dist
+++ b/phpunit.xml.dist
@@ -1,22 +1,20 @@
-
-
- tests/cases/FixturesTest.php
-
-
- tests/cases/PhpcsHelpersTest.php
-
-
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:noNamespaceSchemaLocation="vendor/phpunit/phpunit/phpunit.xsd"
+ bootstrap="tests/bootstrap.php"
+ colors="true">
+
+
+ ./Inpsyde
+
+
+
+
+ tests/cases/FixturesTest.php
+
+
+ tests/cases/PhpcsHelpersTest.php
+
+
diff --git a/psalm.xml b/psalm.xml
index ee09b08..53e46c1 100644
--- a/psalm.xml
+++ b/psalm.xml
@@ -1,11 +1,14 @@
-
-
-
diff --git a/tests/bootstrap.php b/tests/bootstrap.php
index 878abe6..6fd220d 100644
--- a/tests/bootstrap.php
+++ b/tests/bootstrap.php
@@ -1,5 +1,6 @@
-parse($fixtureFile);
+ [$sniffClass, $expected, $properties] = $parser->parse($fixtureFile);
$file = $this->createPhpcsForFixture($sniffClass, $fixtureFile, $properties);
$actual = (new SniffMessagesExtractor($file))->extractMessages();
@@ -105,7 +103,7 @@ private function validateCodes(
SniffMessages $actual,
string $fixture,
string $sniffClass
- ) {
+ ): void {
$where = sprintf("\nin fixture file '%s' line %%d\nfor sniff '%s'", $fixture, $sniffClass);
@@ -136,7 +134,7 @@ private function validateCode(
string $code,
string $where,
string $actualCode = null
- ) {
+ ): void {
$message = $code
? sprintf('Expected %s code \'%s\' was not found', $type, $code)
@@ -158,7 +156,7 @@ private function validateTotals(
SniffMessages $actual,
string $fixtureFile,
string $sniffClass
- ) {
+ ): void {
$expectedTotal = $expected->total();
$actualTotal = $actual->total();
@@ -195,22 +193,20 @@ private function createPhpcsForFixture(
array $properties
): File {
- $sniffName = str_replace('.', DIRECTORY_SEPARATOR, $sniffName) . 'Sniff';
- $sniffFile = getenv('SNIFFS_PATH') . DIRECTORY_SEPARATOR . "{$sniffName}.php";
- if (!file_exists($sniffFile) || !is_readable($sniffFile)) {
+ $sniffFile = str_replace('.', '/', "{$sniffName}Sniff");
+ $sniffPath = getenv('SNIFFS_PATH') . "/{$sniffFile}.php";
+ if (!file_exists($sniffPath) || !is_readable($sniffPath)) {
// phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
- throw new Exception("Non-existent of unreadable sniff file '$sniffFile' found.");
+ throw new Exception("Non-existent of unreadable sniff file '{$sniffPath}' found.");
}
$config = new Config();
- $config->standards = [];
- /** @var Ruleset $ruleset */
- $ruleset = (new \ReflectionClass(Ruleset::class))->newInstanceWithoutConstructor();
- $ruleset->registerSniffs([$sniffFile], [], []);
- $ruleset->populateTokenListeners();
+ $config->standards = [dirname(getenv('SNIFFS_PATH'))];
+ $config->sniffs = ["Inpsyde.{$sniffName}"];
+ $ruleset = new Ruleset($config);
$baseSniffNamespace = getenv('SNIFFS_NAMESPACE');
- $sniffFqn = str_replace(DIRECTORY_SEPARATOR, '\\', $sniffName);
+ $sniffFqn = str_replace('/', '\\', $sniffFile);
foreach ($properties as $name => $value) {
$ruleset->setSniffProperty("{$baseSniffNamespace}\\{$sniffFqn}", $name, $value);
}
diff --git a/tests/cases/PhpcsHelpersTest.php b/tests/cases/PhpcsHelpersTest.php
index d94b1e3..bbdc19e 100644
--- a/tests/cases/PhpcsHelpersTest.php
+++ b/tests/cases/PhpcsHelpersTest.php
@@ -1,5 +1,14 @@
readFile($fixturePath) as $lineNum => $line) {
$this->readLine($lineNum, $line, $accumulator);
}
- // phpcs:enable
return $this->processResults($accumulator, $fixturePath);
}
/**
- * @param \stdClass $accumulator
+ * @param object $accumulator
* @param string $fixturePath
* @return array
*/
- private function processResults(\stdClass $accumulator, string $fixturePath): array
+ private function processResults(object $accumulator, string $fixturePath): array
{
- $results = [
- $accumulator->sniff,
- $accumulator->messages,
- $accumulator->warnings,
- $accumulator->errors,
- $accumulator->properties->values,
- ];
-
if (!$accumulator->process->content) {
return [
- $this->checkSniffName(array_shift($results)),
- new SniffMessages($results[1], $results[2], $results[0]),
+ $this->checkSniffName($accumulator->sniff),
+ new SniffMessages(
+ $accumulator->warnings,
+ $accumulator->errors,
+ $accumulator->messages
+ ),
$accumulator->properties->values,
];
}
// phpcs:disable
eval("\$cb = {$accumulator->process->content};");
- /** @var callable $cb */
- $results = $cb(...$results);
+ $params = [
+ $accumulator->sniff,
+ $accumulator->messages,
+ $accumulator->warnings,
+ $accumulator->errors,
+ $accumulator->properties->values,
+ ];
+ /** @var mixed $cb */
+ $results = is_callable($cb) ? $cb(...$params) : null;
// phpcs:enable
+ $results = array_values(array_pad(is_array($results) ? $results : [], 5, null));
+ [$sniff, $messages, $warnings, $errors, $properties] = $results;
+
if (
- $accumulator->process->content
- && !is_array($results)
- || count($results) !== 5
- || !is_string($results[0] ?? null)
- || !is_array($results[1] ?? null)
- || !is_array($results[2] ?? null)
- || !is_array($results[3] ?? null)
- || !is_array($results[4] ?? null)
+ !is_string($sniff)
+ || !is_array($messages)
+ || !is_array($warnings)
+ || !is_array($errors)
+ || !is_array($properties)
) {
- throw new Exception(
- // phpcs:disable WordPress.Security.EscapeOutput.OutputNotEscaped
+ throw new \Error(
sprintf(
"Process callback for fixture '%s' (lines #%s:#%s) returned invalid output.",
$fixturePath,
$accumulator->process->start,
$accumulator->process->end
)
- // phpcs:enable WordPress.Security.EscapeOutput.OutputNotEscaped
);
}
return [
- $this->checkSniffName(array_shift($results)),
- new SniffMessages($results[1], $results[2], $results[0]),
- $results[3],
+ $this->checkSniffName($sniff),
+ new SniffMessages($warnings, $errors, $messages),
+ $properties,
];
}
@@ -127,10 +122,10 @@ private function processResults(\stdClass $accumulator, string $fixturePath): ar
* @param string|null $sniff
* @return string
*/
- private function checkSniffName(string $sniff = null): string
+ private function checkSniffName(?string $sniff): string
{
if ($sniff === null) {
- throw new Exception("No sniff class found for the test.");
+ throw new \Error("No sniff class found for the test.");
}
static $regex;
@@ -140,8 +135,7 @@ private function checkSniffName(string $sniff = null): string
}
if (!preg_match('~^' . $regex . '$~', $sniff)) {
- // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
- throw new Exception("Invalid sniff name '{$sniff}'.");
+ throw new \Error("Invalid sniff name '{$sniff}'.");
}
return $sniff;
@@ -154,6 +148,10 @@ private function checkSniffName(string $sniff = null): string
private function readFile(string $file): \Generator
{
$handle = fopen($file, 'rb');
+ if ($handle === false) {
+ throw new \Error("Could not open '{$file}' for reading.");
+ }
+
$lineNum = 1;
$line = fgets($handle);
@@ -168,9 +166,9 @@ private function readFile(string $file): \Generator
/**
* @param int $lineNum
* @param string $line
- * @param \stdClass $accumulator
+ * @param object $accumulator
*/
- private function readLine(int $lineNum, string $line, \stdClass $accumulator)
+ private function readLine(int $lineNum, string $line, object $accumulator): void
{
if (
!$this->readProcessLine($lineNum, $line, $accumulator)
@@ -184,10 +182,10 @@ private function readLine(int $lineNum, string $line, \stdClass $accumulator)
/**
* @param int $lineNum
* @param string $line
- * @param \stdClass $accumulator
+ * @param object $accumulator
* @return bool
*/
- private function readProcessLine(int $lineNum, string $line, \stdClass $accumulator): bool
+ private function readProcessLine(int $lineNum, string $line, object $accumulator): bool
{
if ($accumulator->process->end !== false) {
return false;
@@ -213,10 +211,10 @@ private function readProcessLine(int $lineNum, string $line, \stdClass $accumula
/**
* @param string $line
- * @param \stdClass $accumulator
+ * @param object $accumulator
* @return bool
*/
- private function readSniffLine(string $line, \stdClass $accumulator): bool
+ private function readSniffLine(string $line, object $accumulator): bool
{
if ($accumulator->sniff) {
return false;
@@ -238,10 +236,10 @@ private function readSniffLine(string $line, \stdClass $accumulator): bool
/**
* @param int $lineNum
* @param string $line
- * @param \stdClass $accumulator
+ * @param object $accumulator
* @return bool
*/
- private function readPropertiesLine(int $lineNum, string $line, \stdClass $accumulator): bool
+ private function readPropertiesLine(int $lineNum, string $line, object $accumulator): bool
{
static $pattern;
$pattern or $pattern = '~\$([a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*)\s*=\s*([^;]+);~';
@@ -274,9 +272,9 @@ private function readPropertiesLine(int $lineNum, string $line, \stdClass $accum
/**
* @param int $lineNum
* @param string $line
- * @param \stdClass $accumulator
+ * @param object $accumulator
*/
- private function readTokenLine(int $lineNum, string $line, \stdClass $accumulator)
+ private function readTokenLine(int $lineNum, string $line, object $accumulator): void
{
static $pattern;
if (!$pattern) {
diff --git a/tests/src/SniffMessages.php b/tests/src/SniffMessages.php
index c5aa846..339b8f5 100644
--- a/tests/src/SniffMessages.php
+++ b/tests/src/SniffMessages.php
@@ -1,9 +1,6 @@
messagesContainTotal = true;
}
@@ -69,7 +53,7 @@ public function messages(): array
* @param int $line
* @return string|null
*/
- public function messageIn(int $line)
+ public function messageIn(int $line): ?string
{
return $this->messages[$line] ?? null;
}
@@ -99,7 +83,7 @@ public function errors(): array
* @param int $line
* @return string|null
*/
- public function errorIn(int $line)
+ public function errorIn(int $line): ?string
{
return $this->errors[$line] ?? null;
}
@@ -124,7 +108,7 @@ public function warnings(): array
* @param int $line
* @return string|null
*/
- public function warningIn(int $line)
+ public function warningIn(int $line): ?string
{
return $this->warnings[$line] ?? null;
}
diff --git a/tests/src/SniffMessagesExtractor.php b/tests/src/SniffMessagesExtractor.php
index 6f8f8b7..1f98b27 100644
--- a/tests/src/SniffMessagesExtractor.php
+++ b/tests/src/SniffMessagesExtractor.php
@@ -1,9 +1,6 @@
file->process();
- list($warnings, $errors) = $this->normalize(
+ [$warnings, $errors] = $this->normalize(
$this->file->getWarnings(),
$this->file->getErrors()
);
From 6a404be1eb4dfbfe3ba28013a3f783c30a64e72f Mon Sep 17 00:00:00 2001
From: Giuseppe Mazzapica
Date: Sat, 26 Aug 2023 00:29:04 +0200
Subject: [PATCH 8/8] Make use of reusable workflows for QA
---
.github/workflows/php-qa.yml | 76 ---------------------
.github/workflows/quality-assurance-php.yml | 51 ++++++++++++++
2 files changed, 51 insertions(+), 76 deletions(-)
delete mode 100644 .github/workflows/php-qa.yml
create mode 100644 .github/workflows/quality-assurance-php.yml
diff --git a/.github/workflows/php-qa.yml b/.github/workflows/php-qa.yml
deleted file mode 100644
index 8cf444a..0000000
--- a/.github/workflows/php-qa.yml
+++ /dev/null
@@ -1,76 +0,0 @@
-name: PHP Quality Assurance
-on:
- push:
- pull_request:
- workflow_dispatch:
-concurrency:
- group: ${{ github.workflow }}-${{ github.ref }}
- cancel-in-progress: true
-jobs:
- static-qa:
- runs-on: ubuntu-latest
- if: ${{ !contains(github.event.head_commit.message, 'no static qa') }}
- steps:
- - name: Checkout
- uses: actions/checkout@v2
-
- - name: Setup PHP
- uses: shivammathur/setup-php@v2
- with:
- php-version: 7.4
- coverage: none
- tools: cs2pr
-
- - name: Install dependencies
- uses: ramsey/composer-install@v2
-
- - name: Check code styles
- run: |
- ./vendor/bin/phpcs -q --report-full --report-checkstyle="phpcs-report.xml" --runtime-set testVersion 7.0- --runtime-set ignore_errors_on_exit 1 --runtime-set ignore_warnings_on_exit 1
- cs2pr --graceful-warnings phpcs-report.xml
-
- - name: Check Psalm
- run: ./vendor/bin/psalm --output-format=github --no-cache
-
- unit-tests:
- runs-on: ubuntu-latest
- if: ${{ !contains(github.event.head_commit.message, 'no unit tests') }}
- strategy:
- fail-fast: true
- matrix:
- php-ver: [ '7.4', '8.0', '8.1', '8.2' ]
- deps-mode: [ 'lowest', 'highest' ]
- include:
- - php-ver: '8.1'
- dependency-versions: 'highest'
-
- steps:
- - name: Checkout
- uses: actions/checkout@v2
-
- - name: Setup PHP
- uses: shivammathur/setup-php@v2
- with:
- php-version: ${{ matrix.php-ver }}
- ini-values: zend.assertions=1, error_reporting=-1, display_errors=On
- coverage: none
- tools: cs2pr, parallel-lint:^1.3.1
-
- - name: Check syntax error in sources
- if: ${{ (matrix.deps-mode == 'highest') }}
- run: parallel-lint ./Inpsyde/ ./tests/src/ ./tests/cases/ --checkstyle | cs2pr
-
- - name: Remove Psalm before tests to prevent installation conflicts
- run: composer remove vimeo/psalm --no-update
-
- - name: Install dependencies
- uses: ramsey/composer-install@v2
- with:
- dependency-versions: ${{ matrix.deps-mode }}
-
- - name: Migrate PHPUnit config for PHPUnit 9
- if: ${{ (matrix.php-ver >= 7.3) && (matrix.deps-mode == 'highest') }}
- run: ./vendor/bin/phpunit --migrate-configuration
-
- - name: Run unit tests
- run: ./vendor/bin/phpunit --testsuite=unit --no-coverage
diff --git a/.github/workflows/quality-assurance-php.yml b/.github/workflows/quality-assurance-php.yml
new file mode 100644
index 0000000..cee505f
--- /dev/null
+++ b/.github/workflows/quality-assurance-php.yml
@@ -0,0 +1,51 @@
+name: PHP Quality Assurance
+
+on:
+ push:
+ paths:
+ - '**workflows/quality-assurance-php.yml'
+ - '**.php'
+ - '**phpcs.xml.dist'
+ - '**phpunit.xml.dist'
+ - '**psalm.xml'
+ workflow_dispatch:
+ inputs:
+ jobs:
+ required: true
+ type: choice
+ default: 'Run all'
+ description: 'Choose jobs to run'
+ options:
+ - 'Run all'
+ - 'Run PHPCS only'
+ - 'Run Psalm only'
+ - 'Run lint only'
+ - 'Run static analysis'
+ - 'Run unit tests only'
+
+concurrency:
+ group: ${{ github.workflow }}-${{ github.ref }}
+ cancel-in-progress: true
+
+jobs:
+ lint-php:
+ uses: inpsyde/reusable-workflows/.github/workflows/lint-php.yml@main
+ if: ${{ (github.event_name != 'workflow_dispatch') || ((github.event.inputs.jobs == 'Run all') || (github.event.inputs.jobs == 'Run lint only') || (github.event.inputs.jobs == 'Run static analysis')) }}
+ with:
+ PHP_MATRIX: '["7.4", "8.0", "8.1", "8.2"]'
+ LINT_ARGS: '-e php --colors --show-deprecated ./Inpsyde'
+
+ coding-standards-analysis-php:
+ if: ${{ (github.event_name != 'workflow_dispatch') || ((github.event.inputs.jobs == 'Run all') || (github.event.inputs.jobs == 'Run PHPCS only') || (github.event.inputs.jobs == 'Run static analysis')) }}
+ uses: inpsyde/reusable-workflows/.github/workflows/coding-standards-php.yml@main
+
+ static-code-analysis-php:
+ if: ${{ (github.event_name != 'workflow_dispatch') || ((github.event.inputs.jobs == 'Run all') || (github.event.inputs.jobs == 'Run Psalm only') || (github.event.inputs.jobs == 'Run static analysis')) }}
+ uses: inpsyde/reusable-workflows/.github/workflows/static-analysis-php.yml@main
+
+ tests-unit-php:
+ if: ${{ (github.event_name != 'workflow_dispatch') || ((github.event.inputs.jobs == 'Run all') || (github.event.inputs.jobs == 'Run unit tests only')) }}
+ uses: inpsyde/reusable-workflows/.github/workflows/tests-unit-php.yml@main
+ with:
+ PHP_MATRIX: '["7.4", "8.0", "8.1", "8.2"]'
+ PHPUNIT_ARGS: '--no-coverage'