Skip to content

Commit 006e065

Browse files
authored
Add PHP 8.2 support and PHPUnit 10 (#319)
* allow running tests via composer script * Update all dev-dependencies * fix covers warnings * set all dataProvider as static * Improve github Actions, update services, add tests with PHP 8.2 * Run tests with phpunit 10.2, replace deprecated withConsecutive() * catch and tests warnings thrown by SimpleXMLElement * Create composer command to create HTML code-coverage report * Update CHANGELOG.md
1 parent a2e59e7 commit 006e065

18 files changed

+158
-208
lines changed

.github/workflows/tests.yml

Lines changed: 6 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -14,11 +14,11 @@ jobs:
1414
fail-fast: false
1515
matrix:
1616
operating-system: ['ubuntu-latest']
17-
php-versions: ['7.4', '8.0', '8.1']
17+
php-versions: ['7.4', '8.0', '8.1', '8.2']
1818

1919
steps:
2020
- name: Checkout
21-
uses: actions/checkout@v3
21+
uses: actions/checkout@v4
2222
with:
2323
fetch-depth: 2
2424

@@ -32,21 +32,10 @@ jobs:
3232
extensions: mbstring, xml, ctype, iconv, intl, pdo_sqlite
3333
coverage: xdebug
3434

35-
- name: Get composer cache directory
36-
id: composer-cache
37-
run: echo "::set-output name=dir::$(composer config cache-files-dir)"
38-
39-
- name: Cache composer dependencies
40-
uses: actions/cache@v3
41-
with:
42-
path: ${{ steps.composer-cache.outputs.dir }}
43-
# Use composer.json for key, if composer.lock is not committed.
44-
# key: ${{ runner.os }}-composer-${{ hashFiles('**/composer.json') }}
45-
key: ${{ runner.os }}-composer-${{ hashFiles('**/composer.lock') }}
46-
restore-keys: ${{ runner.os }}-composer-
47-
48-
- name: Install Composer dependencies
49-
run: composer install --no-progress --prefer-dist --optimize-autoloader
35+
# Install composer dependencies and handle caching in one go.
36+
# @link https://github.com/marketplace/actions/install-composer-dependencies
37+
- name: "Install Composer dependencies"
38+
uses: "ramsey/composer-install@v2"
5039

5140
- name: Run tests
5241
run: vendor/bin/phpunit --coverage-text

.gitignore

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
.php-cs-fixer.cache
2-
.phpunit.result.cache
2+
.phpunit.cache
33
composer.lock
44
composer.phar
5-
coverage.clover
65
phpunit.xml
76
vendor

CHANGELOG.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
77

88
## [Unreleased](https://github.com/kbsali/php-redmine-api/compare/v2.2.0...v2.x)
99

10+
### Added
11+
12+
- Added support for PHP 8.2
13+
1014
### Deprecated
1115

1216
- `Redmine\Api\AbstractApi::attachCustomFieldXML()` is deprecated
@@ -37,6 +41,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
3741

3842
### Added
3943

44+
- Added support for PHP 8.1
4045
- New interface `Redmine\Exception` that is implemented by every library-related exception
4146
- New exception `Redmine\Exception\ClientException` for client related exceptions
4247
- New exception `Redmine\Exception\InvalidApiNameException` if an invalid API instance is requested

composer.json

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -24,10 +24,10 @@
2424
"psr/http-factory": "^1.0"
2525
},
2626
"require-dev": {
27-
"friendsofphp/php-cs-fixer": "3.11.0",
28-
"phpunit/phpunit": "9.5.10",
29-
"guzzlehttp/psr7": "2.1.0",
30-
"php-mock/php-mock-phpunit": "2.6.0"
27+
"friendsofphp/php-cs-fixer": "^3",
28+
"phpunit/phpunit": "^9 || 10.2.*",
29+
"guzzlehttp/psr7": "^2",
30+
"php-mock/php-mock-phpunit": "^2.6"
3131
},
3232
"autoload": {
3333
"psr-4": {
@@ -38,5 +38,9 @@
3838
"psr-4": {
3939
"Redmine\\Tests\\": "tests/"
4040
}
41+
},
42+
"scripts": {
43+
"coverage": "phpunit --coverage-html=\".phpunit.cache/code-coverage\"",
44+
"test": "phpunit"
4145
}
4246
}

phpunit.xml.dist

Lines changed: 20 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,19 @@
11
<?xml version="1.0" encoding="UTF-8"?>
2-
<phpunit xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" backupGlobals="false" backupStaticAttributes="false" colors="true" convertErrorsToExceptions="true" convertNoticesToExceptions="true" convertWarningsToExceptions="true" processIsolation="false" stopOnFailure="false" bootstrap="vendor/autoload.php" xsi:noNamespaceSchemaLocation="https://schema.phpunit.de/9.3/phpunit.xsd">
3-
<coverage>
4-
<include>
5-
<directory suffix=".php">src/Redmine/</directory>
6-
</include>
7-
<report>
8-
<clover outputFile="coverage.clover"/>
9-
</report>
10-
</coverage>
2+
<phpunit xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
3+
xsi:noNamespaceSchemaLocation="https://schema.phpunit.de/10.3/phpunit.xsd"
4+
bootstrap="vendor/autoload.php"
5+
cacheDirectory=".phpunit.cache"
6+
colors="true"
7+
beStrictAboutCoverageMetadata="false"
8+
beStrictAboutOutputDuringTests="true"
9+
displayDetailsOnIncompleteTests="true"
10+
displayDetailsOnSkippedTests="true"
11+
displayDetailsOnTestsThatTriggerDeprecations="true"
12+
displayDetailsOnTestsThatTriggerErrors="true"
13+
displayDetailsOnTestsThatTriggerNotices="true"
14+
displayDetailsOnTestsThatTriggerWarnings="true"
15+
>
16+
<coverage />
1117
<testsuites>
1218
<testsuite name="all">
1319
<directory suffix="Test.php">tests/Unit/</directory>
@@ -20,4 +26,9 @@
2026
</exclude>
2127
</groups>
2228
<logging/>
29+
<source>
30+
<include>
31+
<directory suffix=".php">src/Redmine/</directory>
32+
</include>
33+
</source>
2334
</phpunit>

src/Redmine/Serializer/XmlSerializer.php

Lines changed: 27 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
namespace Redmine\Serializer;
44

5+
use JsonException;
56
use Redmine\Exception\SerializerException;
67
use SimpleXMLElement;
78
use Throwable;
@@ -64,14 +65,26 @@ private function deserialize(string $encoded): void
6465
{
6566
$this->encoded = $encoded;
6667

68+
$prevSetting = libxml_use_internal_errors(true);
69+
6770
try {
6871
$this->deserialized = new SimpleXMLElement($encoded);
6972
} catch (Throwable $e) {
73+
$errors = [];
74+
75+
foreach (libxml_get_errors() as $error) {
76+
$errors[] = $error->message;
77+
}
78+
79+
libxml_clear_errors();
80+
7081
throw new SerializerException(
71-
'Catched error "' . $e->getMessage() . '" while decoding XML: ' . $encoded,
82+
'Catched errors: "' . implode('", "', $errors) . '" while decoding XML: ' . $encoded,
7283
$e->getCode(),
7384
$e
7485
);
86+
} finally {
87+
libxml_use_internal_errors($prevSetting);
7588
}
7689

7790
$this->normalize($this->deserialized);
@@ -94,14 +107,26 @@ private function denormalize(array $normalized): void
94107

95108
$rootElementName = array_key_first($this->normalized);
96109

110+
$prevSetting = libxml_use_internal_errors(true);
111+
97112
try {
98113
$this->deserialized = $this->createXmlElement($rootElementName, $this->normalized[$rootElementName]);
99114
} catch (Throwable $e) {
115+
$errors = [];
116+
117+
foreach (libxml_get_errors() as $error) {
118+
$errors[] = $error->message;
119+
}
120+
121+
libxml_clear_errors();
122+
100123
throw new SerializerException(
101-
'Could not create XML from array: ' . $e->getMessage(),
124+
'Could not create XML from array: "' . implode('", "', $errors) . '"',
102125
$e->getCode(),
103126
$e
104127
);
128+
} finally {
129+
libxml_use_internal_errors($prevSetting);
105130
}
106131

107132
$this->encoded = $this->deserialized->asXml();

tests/Integration/Psr18ClientRequestGenerationTest.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -107,7 +107,7 @@ public function createStreamFromResource($resource): StreamInterface
107107
$client->$method($path, $data);
108108
}
109109

110-
public function createdGetRequestsData()
110+
public static function createdGetRequestsData(): array
111111
{
112112
return [
113113
[

tests/Unit/Api/AbstractApiTest.php

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ public function testIsNotNullReturnsCorrectBoolean(bool $expected, $value)
3030
$this->assertSame($expected, $method->invoke($api, $value));
3131
}
3232

33-
public function getIsNotNullReturnsCorrectBooleanData()
33+
public static function getIsNotNullReturnsCorrectBooleanData(): array
3434
{
3535
return [
3636
[false, null],
@@ -67,7 +67,7 @@ public function testLastCallFailedReturnsCorrectBoolean($statusCode, $expectedBo
6767
$this->assertSame($expectedBoolean, $api->lastCallFailed());
6868
}
6969

70-
public function getLastCallFailedData()
70+
public static function getLastCallFailedData(): array
7171
{
7272
return [
7373
[100, true],
@@ -161,7 +161,7 @@ public function testJsonDecodingFromGetMethod($response, $decode, $expected)
161161
}
162162
}
163163

164-
public function getJsonDecodingFromGetMethodData()
164+
public static function getJsonDecodingFromGetMethodData(): array
165165
{
166166
return [
167167
['{"foo_bar": 12345}', null, ['foo_bar' => 12345]], // test decode by default
@@ -217,7 +217,7 @@ public function testXmlDecodingFromRequestMethods($methodName, $response, $decod
217217
}
218218
}
219219

220-
public function getXmlDecodingFromGetMethodData()
220+
public static function getXmlDecodingFromGetMethodData(): array
221221
{
222222
return [
223223
['get', '<?xml version="1.0"?><issue/>', null, '<?xml version="1.0"?><issue/>'], // test decode by default

tests/Unit/Api/AttachmentTest.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ public function testLastCallFailedTrue($responseCode, $hasFailed)
4444
*
4545
* @return array[]
4646
*/
47-
public function responseCodeProvider()
47+
public static function responseCodeProvider(): array
4848
{
4949
return [
5050
[199, true],

tests/Unit/Api/IssueTest.php

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
*/
1414
class IssueTest extends TestCase
1515
{
16-
public function getPriorityConstantsData()
16+
public static function getPriorityConstantsData(): array
1717
{
1818
return [
1919
[1, Issue::PRIO_LOW],
@@ -475,7 +475,6 @@ public function testCreateCleansParameters()
475475
* Test create() and buildXML().
476476
*
477477
* @covers ::create
478-
* @covers ::buildXML
479478
* @covers ::attachCustomFieldXML
480479
* @test
481480
*/
@@ -719,7 +718,6 @@ public function testAddNoteToIssue()
719718
/**
720719
* Test buildXML().
721720
*
722-
* @covers ::buildXML
723721
* @test
724722
*/
725723
public function testBuildXmlWithCustomFields()
@@ -760,7 +758,6 @@ public function testBuildXmlWithCustomFields()
760758
/**
761759
* Test buildXML().
762760
*
763-
* @covers ::buildXML
764761
* @test
765762
*/
766763
public function testBuildXmlWithWatchers()
@@ -796,7 +793,6 @@ public function testBuildXmlWithWatchers()
796793
/**
797794
* Test buildXML().
798795
*
799-
* @covers ::buildXML
800796
* @test
801797
*/
802798
public function testBuildXmlWithUploads()
@@ -857,7 +853,6 @@ public function testBuildXmlWithUploads()
857853
/**
858854
* Test buildXML().
859855
*
860-
* @covers ::buildXML
861856
* @test
862857
*/
863858
public function testBuildXmlWithWatcherAndUploadAndCustomFieldAndStandard()

0 commit comments

Comments
 (0)