Skip to content

Commit e61047c

Browse files
authored
Merge pull request #52 from voku/copilot/fix-github-ci-errors
Restore CI for PHP 7.1+ with versioned PHPUnit configs and PHPStan cleanup
2 parents 8644243 + a7d1e33 commit e61047c

10 files changed

Lines changed: 142 additions & 37 deletions

.github/workflows/ci.yml

Lines changed: 41 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -16,19 +16,45 @@ jobs:
1616
strategy:
1717
fail-fast: false
1818
matrix:
19-
php: [
20-
7.1,
21-
7.2,
22-
7.3
23-
7.4,
24-
8.0,
25-
8.1,
26-
8.2,
27-
8.3,
28-
8.4,
29-
8.5
30-
]
31-
composer: [basic]
19+
# Keep the "modern" leg on PHPUnit 9 until the suite is upgraded for
20+
# PHPUnit 10+, so CI currently stops at PHP 8.4.
21+
include:
22+
- php: '7.1'
23+
composer: basic
24+
phpunit: '^7.5'
25+
phpunit_config: phpunit.legacy.xml.dist
26+
- php: '7.2'
27+
composer: basic
28+
phpunit: '^8.5'
29+
phpunit_config: phpunit.legacy.xml.dist
30+
- php: '7.3'
31+
composer: basic
32+
phpunit: '^9.6'
33+
phpunit_config: phpunit.xml.dist
34+
- php: '7.4'
35+
composer: basic
36+
phpunit: '^9.6'
37+
phpunit_config: phpunit.xml.dist
38+
- php: '8.0'
39+
composer: basic
40+
phpunit: '^9.6'
41+
phpunit_config: phpunit.xml.dist
42+
- php: '8.1'
43+
composer: basic
44+
phpunit: '^9.6'
45+
phpunit_config: phpunit.xml.dist
46+
- php: '8.2'
47+
composer: basic
48+
phpunit: '^9.6'
49+
phpunit_config: phpunit.xml.dist
50+
- php: '8.3'
51+
composer: basic
52+
phpunit: '^9.6'
53+
phpunit_config: phpunit.xml.dist
54+
- php: '8.4'
55+
composer: basic
56+
phpunit: '^9.6'
57+
phpunit_config: phpunit.xml.dist
3258
timeout-minutes: 10
3359
steps:
3460
- name: Checkout code
@@ -57,6 +83,7 @@ jobs:
5783

5884
- name: Install dependencies
5985
run: |
86+
composer require --dev --no-update "phpunit/phpunit:${{ matrix.phpunit }}"
6087
if [[ "${{ matrix.composer }}" == "lowest" ]]; then
6188
composer update --prefer-dist --no-interaction --prefer-lowest --prefer-stable
6289
fi;
@@ -70,7 +97,7 @@ jobs:
7097
- name: Run tests
7198
run: |
7299
mkdir -p build/logs
73-
XDEBUG_MODE=coverage php vendor/bin/phpunit -c phpunit.xml.dist
100+
XDEBUG_MODE=coverage php vendor/bin/phpunit -c "${{ matrix.phpunit_config }}"
74101
75102
- name: Run phpstan
76103
continue-on-error: true

phpstan.neon

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,14 @@
11
parameters:
2+
# Analyze against the minimum supported runtime so PHP 7.1 compatibility
3+
# issues are caught even when phpstan itself runs on a newer PHP in CI.
4+
phpVersion: 70100
25
level: 8
36
paths:
47
- %currentWorkingDirectory%/src/
8+
excludePaths:
9+
# This file is only loaded on PHP 8.1+ by JsonSerializableReturnTypeTrait.php.
10+
# It defines the same trait name, so excluding it prevents a duplicate-symbol error.
11+
- %currentWorkingDirectory%/src/JsonSerializableReturnTypeTraitPhp81.php
512
reportUnmatchedIgnoredErrors: false
613
ignoreErrors:
714
# false-positive?

phpunit.legacy.xml.dist

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
<?xml version="1.0"?>
2+
<phpunit>
3+
<filter>
4+
<whitelist processUncoveredFilesFromWhitelist="true">
5+
<directory suffix=".php">./src/</directory>
6+
<exclude>
7+
<!-- Loaded conditionally by JsonSerializableReturnTypeTrait.php on PHP 8.1+;
8+
including it unconditionally here would re-declare the trait on PHP < 8.1. -->
9+
<file>./src/JsonSerializableReturnTypeTraitPhp81.php</file>
10+
</exclude>
11+
</whitelist>
12+
</filter>
13+
<logging>
14+
<log type="coverage-clover" target="build/logs/clover.xml"/>
15+
</logging>
16+
<testsuites>
17+
<testsuite name="Stringy">
18+
<directory>tests</directory>
19+
</testsuite>
20+
</testsuites>
21+
</phpunit>

phpunit.xml.dist

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,11 @@
44
<include>
55
<directory suffix=".php">./src/</directory>
66
</include>
7+
<exclude>
8+
<!-- Loaded conditionally by JsonSerializableReturnTypeTrait.php on PHP 8.1+;
9+
including it unconditionally here would re-declare the trait on PHP < 8.1. -->
10+
<file>./src/JsonSerializableReturnTypeTraitPhp81.php</file>
11+
</exclude>
712
<report>
813
<clover outputFile="build/logs/clover.xml"/>
914
</report>
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Stringy;
6+
7+
if (\PHP_VERSION_ID < 80100) {
8+
trait JsonSerializableReturnTypeTrait
9+
{
10+
/**
11+
* Returns value which can be serialized by json_encode().
12+
*
13+
* @psalm-mutation-free
14+
*
15+
* @return string The current value of the $str property
16+
*/
17+
public function jsonSerialize()
18+
{
19+
return (string) $this;
20+
}
21+
}
22+
} else {
23+
require_once __DIR__ . '/JsonSerializableReturnTypeTraitPhp81.php';
24+
}
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Stringy;
6+
7+
trait JsonSerializableReturnTypeTrait
8+
{
9+
/**
10+
* Returns value which can be serialized by json_encode().
11+
*
12+
* PHP 8.1+ deprecates omitting the jsonSerialize() return type when
13+
* implementing JsonSerializable, but PHP 7.1 cannot parse the attribute.
14+
*
15+
* @psalm-mutation-free
16+
*
17+
* @return string The current value of the $str property
18+
*/
19+
#[\ReturnTypeWillChange]
20+
public function jsonSerialize()
21+
{
22+
return (string) $this;
23+
}
24+
}

src/StaticStringy.php

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,8 @@
1818
* @method static string[] chars(string $stringInput, ?string $encoding = null)
1919
* @method static Stringy collapseWhitespace(string $stringInput, ?string $encoding = null)
2020
* @method static bool contains(string $stringInput, string $needle, bool $caseSensitive = true, ?string $encoding = null)
21-
* @method static bool containsAll(string $stringInput, array $needle, bool $caseSensitive = true, ?string $encoding = null)
22-
* @method static bool containsAny(string $stringInput, string $needle, bool $caseSensitive = true, ?string $encoding = null)
21+
* @method static bool containsAll(string $stringInput, string[] $needle, bool $caseSensitive = true, ?string $encoding = null)
22+
* @method static bool containsAny(string $stringInput, string[] $needle, bool $caseSensitive = true, ?string $encoding = null)
2323
* @method static int count(string $stringInput, ?string $encoding = null)
2424
* @method static int countSubstr(string $stringInput, string $substring, bool $caseSensitive = true, ?string $encoding = null)
2525
* @method static Stringy dasherize(string $stringInput, ?string $encoding = null)
@@ -32,8 +32,8 @@
3232
* @method static Stringy first(string $stringInput, int $n, ?string $encoding = null)
3333
* @method static bool hasLowerCase(string $stringInput, ?string $encoding = null)
3434
* @method static bool hasUpperCase(string $stringInput, ?string $encoding = null)
35-
* @method static Stringy htmlDecode(string $stringInput, int $flags = ENT_COMPAT, ?string $encoding = null)
36-
* @method static Stringy htmlEncode(string $stringInput, int $flags = ENT_COMPAT, ?string $encoding = null)
35+
* @method static Stringy htmlDecode(string $stringInput, int $flags, ?string $encoding = null)
36+
* @method static Stringy htmlEncode(string $stringInput, int $flags, ?string $encoding = null)
3737
* @method static Stringy humanize(string $stringInput, ?string $encoding = null)
3838
* @method static int|bool indexOf(string $stringInput, string $needle, int $offset = 0, ?string $encoding = null)
3939
* @method static int|bool indexOfLast(string $stringInput, string $needle, int $offset = 0, ?string $encoding = null)
@@ -71,12 +71,12 @@
7171
* @method static Stringy removeXss(string $stringInput, ?string $encoding = null)
7272
* @method static Stringy repeat(string $stringInput, int $multiplier, ?string $encoding = null)
7373
* @method static Stringy replace(string $stringInput, string $search, string $replacement, bool $caseSensitive, ?string $encoding = null)
74-
* @method static Stringy replaceAll(string $stringInput, array $search, string $replacement, bool $caseSensitive, ?string $encoding = null)
74+
* @method static Stringy replaceAll(string $stringInput, string[] $search, string|string[] $replacement, bool $caseSensitive, ?string $encoding = null)
7575
* @method static Stringy reverse(string $stringInput, ?string $encoding = null)
7676
* @method static Stringy safeTruncate(string $stringInput, int $length, string $substring = '', ?string $encoding = null)
7777
* @method static Stringy shuffle(string $stringInput, ?string $encoding = null)
7878
* @method static Stringy shortenAfterWord(string $stringInput, int $length, string $strAddOn)
79-
* @method static Stringy slugify(string $stringInput, string $separator = '-', string $language = 'en', array $replacements = [], ?string $encoding = null)
79+
* @method static Stringy slugify(string $stringInput, string $separator = '-', string $language = 'en', array<string, string> $replacements = [], ?string $encoding = null)
8080
* @method static Stringy stripeCssMediaQueries(string $stringInput)
8181
* @method static Stringy stripeEmptyHtmlTags(string $stringInput)
8282
* @method static Stringy utf8ify(string $stringInput)

src/Stringy.php

Lines changed: 4 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,8 @@
3333
*/
3434
class Stringy implements \ArrayAccess, \Countable, \IteratorAggregate, \JsonSerializable
3535
{
36+
use JsonSerializableReturnTypeTrait;
37+
3638
/**
3739
* An instance's string.
3840
*
@@ -2503,21 +2505,6 @@ public function isWhitespace(): bool
25032505
return $this->isBlank();
25042506
}
25052507

2506-
/**
2507-
* Returns value which can be serialized by json_encode().
2508-
*
2509-
* EXAMPLE: <code>
2510-
* </code>
2511-
*
2512-
* @psalm-mutation-free
2513-
*
2514-
* @return string The current value of the $str property
2515-
*/
2516-
public function jsonSerialize(): mixed
2517-
{
2518-
return (string) $this;
2519-
}
2520-
25212508
/**
25222509
* Convert the string to kebab-case.
25232510
*
@@ -4988,6 +4975,8 @@ public function urlEncodeRaw(): self
49884975
* @return static
49894976
* <p>Object whose $str has been converted to an URL slug.</p>
49904977
*
4978+
* @phpstan-param ASCII::*_LANGUAGE_CODE $language
4979+
*
49914980
* @psalm-suppress ImpureMethodCall :/
49924981
*/
49934982
public function urlify(

tests/StringyStrictTest.php

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1909,7 +1909,11 @@ public function testAppendRandomStringProducesCorrectChars()
19091909
{
19101910
$result = S::create('')->appendRandomString(8, 'abc');
19111911
static::assertSame(8, $result->length());
1912-
static::assertMatchesRegularExpression('/^[abc]{8}$/', $result->toString());
1912+
if (\method_exists(__CLASS__, 'assertMatchesRegularExpression')) {
1913+
static::assertMatchesRegularExpression('/^[abc]{8}$/', $result->toString());
1914+
} else {
1915+
static::assertRegExp('/^[abc]{8}$/', $result->toString());
1916+
}
19131917
}
19141918

19151919
public function testAddUniqueIdentifier()

tests/StringyTest.php

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1907,7 +1907,11 @@ public function testAppendRandomStringProducesCorrectChars()
19071907
{
19081908
$result = S::create('')->appendRandomString(8, 'abc');
19091909
static::assertSame(8, $result->length());
1910-
static::assertMatchesRegularExpression('/^[abc]{8}$/', $result->toString());
1910+
if (\method_exists(__CLASS__, 'assertMatchesRegularExpression')) {
1911+
static::assertMatchesRegularExpression('/^[abc]{8}$/', $result->toString());
1912+
} else {
1913+
static::assertRegExp('/^[abc]{8}$/', $result->toString());
1914+
}
19111915
}
19121916

19131917
public function testAddUniqueIdentifier()

0 commit comments

Comments
 (0)