Skip to content

Commit 731f6e1

Browse files
minor #495 Give testing some love (nicolas-grekas)
This PR was merged into the 1.x branch. Discussion ---------- Give testing some love `./phpunit` FTW + some goodies Commits ------- 1c3f8e8 Give testing some love
2 parents 2ae3bda + 1c3f8e8 commit 731f6e1

18 files changed

+111
-67
lines changed

.github/workflows/tests.yml

+4-3
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,6 @@ jobs:
1212

1313
env:
1414
COMPOSER_ROOT_VERSION: 1.x-dev
15-
SYMFONY_PHPUNIT_VERSION: 8.5
1615

1716
strategy:
1817
matrix:
@@ -41,10 +40,12 @@ jobs:
4140
tools: "composer:v2"
4241

4342
- name: Install dependencies
44-
run: composer --prefer-source --no-progress --ansi install
43+
run: |
44+
composer --prefer-source --no-progress --ansi install
45+
./phpunit install
4546
4647
- name: Run tests
4748
run: |
4849
ok=0
49-
./vendor/bin/simple-phpunit || ok=1
50+
./phpunit || ok=1
5051
[[ "${{ matrix.mode }}" = experimental ]] || (exit $ok)

.gitignore

+1
Original file line numberDiff line numberDiff line change
@@ -3,5 +3,6 @@
33
.phpunit.result.cache
44
composer.lock
55
phpunit.xml
6+
.phpunit
67
vendor/
78
/tests/unicode

appveyor.yml

+3-3
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,8 @@ cache:
1010
init:
1111
- SET PATH=c:\php;%PATH%
1212
- SET COMPOSER_NO_INTERACTION=1
13+
- SET COMPOSER_ROOT_VERSION=1.x-dev
1314
- SET PHP=1
14-
- SET SYMFONY_PHPUNIT_VERSION=8.5
1515

1616
install:
1717
- cinst wget
@@ -41,8 +41,8 @@ install:
4141
- appveyor DownloadFile https://github.com/composer/composer/releases/download/2.7.9/composer.phar
4242
- cd c:\projects\polyfill
4343
- mkdir %APPDATA%\Composer && copy /Y .github\composer-config.json %APPDATA%\Composer\config.json
44-
- SET COMPOSER_ROOT_VERSION=1.x-dev
4544
- composer update --prefer-source --no-progress --ansi
45+
- php -d allow_url_fopen=0 ./phpunit install
4646

4747
test_script:
48-
- php -d allow_url_fopen=0 ./vendor/symfony/phpunit-bridge/bin/simple-phpunit
48+
- php -d allow_url_fopen=0 ./phpunit

phpunit

+13
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
#!/usr/bin/env php
2+
<?php
3+
4+
if (!file_exists(__DIR__.'/vendor/symfony/phpunit-bridge/bin/simple-phpunit')) {
5+
echo "Unable to find the `simple-phpunit` script in `vendor/symfony/phpunit-bridge/bin/`.\nPlease run `composer update` before running this command.\n";
6+
exit(1);
7+
}
8+
if (!getenv('SYMFONY_PHPUNIT_VERSION')) {
9+
putenv('SYMFONY_PHPUNIT_VERSION=8.5');
10+
}
11+
12+
putenv('SYMFONY_PHPUNIT_DIR='.__DIR__.'/.phpunit');
13+
require __DIR__.'/vendor/symfony/phpunit-bridge/bin/simple-phpunit';

src/Apcu/bootstrap80.php

+1-1
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ function apcu_delete($key): array|bool { return p\Apcu::apcu_delete($key); }
2222
function apcu_exists($key): array|bool { return p\Apcu::apcu_exists($key); }
2323
}
2424
if (!function_exists('apcu_fetch')) {
25-
function apcu_fetch($key, &$success = null): mixed { return p\Apcu::apcu_fetch($key, $success); }
25+
function apcu_fetch($key, &$success = null) { return p\Apcu::apcu_fetch($key, $success); }
2626
}
2727
if (!function_exists('apcu_store')) {
2828
function apcu_store($key, mixed $value, ?int $ttl = 0): array|bool { return p\Apcu::apcu_store($key, $value, (int) $ttl); }

src/Intl/Idn/Idn.php

+8
Original file line numberDiff line numberDiff line change
@@ -145,6 +145,10 @@ final class Idn
145145
*/
146146
public static function idn_to_ascii($domainName, $options = self::IDNA_DEFAULT, $variant = self::INTL_IDNA_VARIANT_UTS46, &$idna_info = [])
147147
{
148+
if (\PHP_VERSION_ID > 80400 && '' === $domainName) {
149+
throw new \ValueError('idn_to_ascii(): Argument #1 ($domain) cannot be empty');
150+
}
151+
148152
if (self::INTL_IDNA_VARIANT_2003 === $variant) {
149153
@trigger_error('idn_to_ascii(): INTL_IDNA_VARIANT_2003 is deprecated', \E_USER_DEPRECATED);
150154
}
@@ -198,6 +202,10 @@ public static function idn_to_ascii($domainName, $options = self::IDNA_DEFAULT,
198202
*/
199203
public static function idn_to_utf8($domainName, $options = self::IDNA_DEFAULT, $variant = self::INTL_IDNA_VARIANT_UTS46, &$idna_info = [])
200204
{
205+
if (\PHP_VERSION_ID > 80400 && '' === $domainName) {
206+
throw new \ValueError('idn_to_utf8(): Argument #1 ($domain) cannot be empty');
207+
}
208+
201209
if (self::INTL_IDNA_VARIANT_2003 === $variant) {
202210
@trigger_error('idn_to_utf8(): INTL_IDNA_VARIANT_2003 is deprecated', \E_USER_DEPRECATED);
203211
}

src/Mbstring/bootstrap80.php

+2-2
Original file line numberDiff line numberDiff line change
@@ -133,11 +133,11 @@ function mb_str_pad(string $string, int $length, string $pad_string = ' ', int $
133133
}
134134

135135
if (!function_exists('mb_ucfirst')) {
136-
function mb_ucfirst($string, ?string $encoding = null): string { return p\Mbstring::mb_ucfirst($string, $encoding); }
136+
function mb_ucfirst(string $string, ?string $encoding = null): string { return p\Mbstring::mb_ucfirst($string, $encoding); }
137137
}
138138

139139
if (!function_exists('mb_lcfirst')) {
140-
function mb_lcfirst($string, ?string $encoding = null): string { return p\Mbstring::mb_lcfirst($string, $encoding); }
140+
function mb_lcfirst(string $string, ?string $encoding = null): string { return p\Mbstring::mb_lcfirst($string, $encoding); }
141141
}
142142

143143
if (!function_exists('mb_trim')) {

src/Php84/bootstrap.php

+2-2
Original file line numberDiff line numberDiff line change
@@ -41,11 +41,11 @@ function array_all(array $array, callable $callback): bool { return p\Php84::arr
4141

4242
if (extension_loaded('mbstring')) {
4343
if (!function_exists('mb_ucfirst')) {
44-
function mb_ucfirst($string, ?string $encoding = null): string { return p\Php84::mb_ucfirst($string, $encoding); }
44+
function mb_ucfirst(string $string, ?string $encoding = null): string { return p\Php84::mb_ucfirst($string, $encoding); }
4545
}
4646

4747
if (!function_exists('mb_lcfirst')) {
48-
function mb_lcfirst($string, ?string $encoding = null): string { return p\Php84::mb_lcfirst($string, $encoding); }
48+
function mb_lcfirst(string $string, ?string $encoding = null): string { return p\Php84::mb_lcfirst($string, $encoding); }
4949
}
5050

5151
if (!function_exists('mb_trim')) {

src/Util/TestListenerForV7.php

+8-13
Original file line numberDiff line numberDiff line change
@@ -23,13 +23,11 @@
2323
*/
2424
class TestListenerForV7 extends TestSuite implements TestListenerInterface
2525
{
26-
private $suite;
2726
private $trait;
2827

2928
public function __construct(?TestSuite $suite = null)
3029
{
3130
if ($suite) {
32-
$this->suite = $suite;
3331
$this->setName($suite->getName().' with polyfills enabled');
3432
$this->addTest($suite);
3533
}
@@ -38,7 +36,13 @@ public function __construct(?TestSuite $suite = null)
3836

3937
public function startTestSuite(TestSuite $suite): void
4038
{
41-
$this->trait->startTestSuite($suite);
39+
if (null === TestListenerTrait::$enabledPolyfills) {
40+
TestListenerTrait::$enabledPolyfills = false;
41+
$this->trait->startTestSuite($suite);
42+
}
43+
if ($suite instanceof TestListener) {
44+
TestListenerTrait::$enabledPolyfills = $suite->getName();
45+
}
4246
}
4347

4448
public function addError(Test $test, \Throwable $t, float $time): void
@@ -69,6 +73,7 @@ public function addSkippedTest(Test $test, \Throwable $t, float $time): void
6973

7074
public function endTestSuite(TestSuite $suite): void
7175
{
76+
TestListenerTrait::$enabledPolyfills = false;
7277
}
7378

7479
public function startTest(Test $test): void
@@ -83,14 +88,4 @@ public static function warning($message): WarningTestCase
8388
{
8489
return new WarningTestCase($message);
8590
}
86-
87-
protected function setUp(): void
88-
{
89-
TestListenerTrait::$enabledPolyfills = $this->suite->getName();
90-
}
91-
92-
protected function tearDown(): void
93-
{
94-
TestListenerTrait::$enabledPolyfills = false;
95-
}
9691
}

src/Util/TestListenerForV9.php

+8-13
Original file line numberDiff line numberDiff line change
@@ -20,13 +20,11 @@
2020

2121
class TestListenerForV9 extends TestSuite implements TestListenerInterface
2222
{
23-
private $suite;
2423
private $trait;
2524

2625
public function __construct(?TestSuite $suite = null)
2726
{
2827
if ($suite) {
29-
$this->suite = $suite;
3028
$this->setName($suite->getName().' with polyfills enabled');
3129
$this->addTest($suite);
3230
}
@@ -35,7 +33,13 @@ public function __construct(?TestSuite $suite = null)
3533

3634
public function startTestSuite(TestSuite $suite): void
3735
{
38-
$this->trait->startTestSuite($suite->tests()[0]);
36+
if (null === TestListenerTrait::$enabledPolyfills) {
37+
TestListenerTrait::$enabledPolyfills = false;
38+
$this->trait->startTestSuite($suite);
39+
}
40+
if ($suite instanceof TestListener) {
41+
TestListenerTrait::$enabledPolyfills = $suite->getName();
42+
}
3943
}
4044

4145
public function addError(Test $test, \Throwable $t, float $time): void
@@ -69,6 +73,7 @@ public function addSkippedTest(Test $test, \Throwable $t, float $time): void
6973

7074
public function endTestSuite(TestSuite $suite): void
7175
{
76+
TestListenerTrait::$enabledPolyfills = false;
7277
}
7378

7479
public function startTest(Test $test): void
@@ -83,14 +88,4 @@ public static function warning($message): WarningTestCase
8388
{
8489
return new WarningTestCase($message);
8590
}
86-
87-
protected function setUp(): void
88-
{
89-
TestListenerTrait::$enabledPolyfills = $this->suite->getName();
90-
}
91-
92-
protected function tearDown(): void
93-
{
94-
TestListenerTrait::$enabledPolyfills = false;
95-
}
9691
}

src/Util/TestListenerTrait.php

+12-6
Original file line numberDiff line numberDiff line change
@@ -25,10 +25,6 @@ class TestListenerTrait
2525

2626
public function startTestSuite($mainSuite)
2727
{
28-
if (null !== self::$enabledPolyfills) {
29-
return;
30-
}
31-
self::$enabledPolyfills = false;
3228
$warnings = [];
3329

3430
foreach ($mainSuite->tests() as $suite) {
@@ -109,7 +105,7 @@ public function startTestSuite($mainSuite)
109105
110106
function {$f['name']}{$f['signature']}
111107
{
112-
if ('{$testClass}' === TestListenerTrait::\$enabledPolyfills) {
108+
if ('{$testClass} with polyfills enabled' === TestListenerTrait::\$enabledPolyfills) {
113109
{$f['return']}{$f['args']};
114110
}
115111
@@ -123,6 +119,16 @@ function {$f['name']}{$f['signature']}
123119
$polyfillSignature = ReflectionCaster::castFunctionAbstract(new \ReflectionFunction($testNamespace.'\\'.$f['name']), [], new Stub(), true);
124120
$polyfillSignature = ReflectionCaster::getSignature($polyfillSignature);
125121

122+
if ('mb_get_info' === $r->name && false === strpos($originalSignature, '|null') && false !== strpos($polyfillSignature, '|null')) {
123+
// Added to PHP 8.2.14/8.3.1
124+
$originalSignature .= '|null';
125+
}
126+
127+
if (false === strpos($bootstrap->getPath(), '80.php')) {
128+
// mixed return type cannot be used before PHP 8
129+
$originalSignature = str_replace(': mixed', '', $originalSignature);
130+
}
131+
126132
$map = [
127133
'?' => '',
128134
'IDNA_DEFAULT' => \PHP_VERSION_ID >= 80100 ? 'IDNA_DEFAULT' : '0',
@@ -131,7 +137,7 @@ function {$f['name']}{$f['signature']}
131137
'array|string|null $from_encoding' => 'array|string $from_encoding',
132138
];
133139

134-
if (strtr($polyfillSignature, $map) !== $originalSignature) {
140+
if (strtr($polyfillSignature, $map) !== str_replace('?', '', $originalSignature)) {
135141
$warnings[] = TestListener::warning("Incompatible signature for PHP >= 8:\n- {$f['name']}$originalSignature\n+ {$f['name']}$polyfillSignature");
136142
}
137143
}

tests/Compiler.php

+1-1
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616
* and charset data to a format suitable for other Utf8 classes.
1717
*
1818
* See https://unicode.org/Public/UNIDATA/ for unicode data
19-
* See https://github.com/unicode-org/cldr/blob/master/common/transforms/ for Latin-ASCII.xml
19+
* See https://github.com/unicode-org/cldr/blob/main/common/transforms/ for Latin-ASCII.xml
2020
*
2121
* @author Nicolas Grekas <[email protected]>
2222
*

tests/Intl/Icu/AbstractIntlDateFormatterTest.php

+22-11
Original file line numberDiff line numberDiff line change
@@ -35,11 +35,11 @@ public function testConstructorDefaultTimeZone()
3535
{
3636
$formatter = $this->getDateFormatter('en', IntlDateFormatter::MEDIUM, IntlDateFormatter::SHORT);
3737

38-
$this->assertEquals(date_default_timezone_get(), $formatter->getTimeZoneId());
38+
$this->assertSame(date_default_timezone_get(), $formatter->getTimeZoneId());
3939

40-
$this->assertEquals(
40+
$this->assertSame(
4141
$this->getDateTime(0, $formatter->getTimeZoneId())->format('M j, Y, g:i A'),
42-
$formatter->format(0)
42+
str_replace("\u{202F}", ' ', $formatter->format(0))
4343
);
4444
}
4545

@@ -50,7 +50,7 @@ public function testConstructorWithoutDateType()
5050
{
5151
$formatter = $this->getDateFormatter('en', null, IntlDateFormatter::SHORT, 'UTC', IntlDateFormatter::GREGORIAN);
5252

53-
$this->assertSame('EEEE, MMMM d, y \'at\' h:mm a', $formatter->getPattern());
53+
$this->assertSame('EEEE, MMMM d, y \'at\' h:mm a', str_replace("\u{202F}", ' ', $formatter->getPattern()));
5454
}
5555

5656
/**
@@ -60,7 +60,7 @@ public function testConstructorWithoutTimeType()
6060
{
6161
$formatter = $this->getDateFormatter('en', IntlDateFormatter::SHORT, null, 'UTC', IntlDateFormatter::GREGORIAN);
6262

63-
$this->assertSame('M/d/yy, h:mm:ss a zzzz', $formatter->getPattern());
63+
$this->assertSame('M/d/yy, h:mm:ss a zzzz', str_replace("\u{202F}", ' ', $formatter->getPattern()));
6464
}
6565

6666
/**
@@ -498,7 +498,11 @@ public function testFormatIgnoresPatternForRelativeDateType()
498498
$datetime = \DateTime::createFromFormat('U', time(), new \DateTimeZone('GMT'));
499499
$datetime->setTime(0, 0, 0);
500500

501-
$this->assertSame('today at 12:00:00 AM Greenwich Mean Time', $formatter->format($datetime));
501+
$formatted = $formatter->format($datetime);
502+
$formatted = str_replace(' at ', ', ', $formatted);
503+
$formatted = str_replace("\u{202F}", ' ', $formatted);
504+
505+
$this->assertSame('today, 12:00:00 AM Greenwich Mean Time', $formatted);
502506
}
503507

504508
/**
@@ -507,7 +511,7 @@ public function testFormatIgnoresPatternForRelativeDateType()
507511
public function testDateAndTimeType($timestamp, $datetype, $timetype, $expected)
508512
{
509513
$formatter = $this->getDateFormatter('en', $datetype, $timetype, 'UTC');
510-
$this->assertSame($expected, $formatter->format($timestamp));
514+
$this->assertSame($expected, str_replace("\u{202F}", ' ', $formatter->format($timestamp)));
511515
}
512516

513517
public static function dateAndTimeTypeProvider()
@@ -533,7 +537,14 @@ public function testRelativeDateType($timestamp, $datetype, $timetype, $expected
533537
$datetime->setTime(0, 0, 0);
534538

535539
$formatter = $this->getDateFormatter('en', $datetype, $timetype, 'UTC');
536-
$this->assertSame($expected, $formatter->format($datetime));
540+
541+
$formatted = $formatter->format($datetime);
542+
543+
// Ignore differences that vary by version of PHP or ICU
544+
$formatted = str_replace(' at ', ', ', $formatted);
545+
$formatted = str_replace("\u{202F}", ' ', $formatted);
546+
547+
$this->assertSame($expected, $formatted);
537548
}
538549

539550
public static function relativeDateTypeProvider()
@@ -545,17 +556,17 @@ public static function relativeDateTypeProvider()
545556
[0, IntlDateFormatter::RELATIVE_SHORT, IntlDateFormatter::NONE, '1/1/70'],
546557

547558
[time(), IntlDateFormatter::RELATIVE_FULL, IntlDateFormatter::NONE, 'today'],
548-
[time(), IntlDateFormatter::RELATIVE_LONG, IntlDateFormatter::FULL, 'today at 12:00:00 AM Coordinated Universal Time'],
559+
[time(), IntlDateFormatter::RELATIVE_LONG, IntlDateFormatter::FULL, 'today, 12:00:00 AM Coordinated Universal Time'],
549560
[time(), IntlDateFormatter::RELATIVE_MEDIUM, IntlDateFormatter::LONG, 'today, 12:00:00 AM UTC'],
550561
[time(), IntlDateFormatter::RELATIVE_SHORT, IntlDateFormatter::SHORT, 'today, 12:00 AM'],
551562

552563
[strtotime('-1 day', time()), IntlDateFormatter::RELATIVE_FULL, IntlDateFormatter::NONE, 'yesterday'],
553-
[strtotime('-1 day', time()), IntlDateFormatter::RELATIVE_LONG, IntlDateFormatter::FULL, 'yesterday at 12:00:00 AM Coordinated Universal Time'],
564+
[strtotime('-1 day', time()), IntlDateFormatter::RELATIVE_LONG, IntlDateFormatter::FULL, 'yesterday, 12:00:00 AM Coordinated Universal Time'],
554565
[strtotime('-1 day', time()), IntlDateFormatter::RELATIVE_MEDIUM, IntlDateFormatter::LONG, 'yesterday, 12:00:00 AM UTC'],
555566
[strtotime('-1 day', time()), IntlDateFormatter::RELATIVE_SHORT, IntlDateFormatter::SHORT, 'yesterday, 12:00 AM'],
556567

557568
[strtotime('+1 day', time()), IntlDateFormatter::RELATIVE_FULL, IntlDateFormatter::NONE, 'tomorrow'],
558-
[strtotime('+1 day', time()), IntlDateFormatter::RELATIVE_LONG, IntlDateFormatter::FULL, 'tomorrow at 12:00:00 AM Coordinated Universal Time'],
569+
[strtotime('+1 day', time()), IntlDateFormatter::RELATIVE_LONG, IntlDateFormatter::FULL, 'tomorrow, 12:00:00 AM Coordinated Universal Time'],
559570
[strtotime('+1 day', time()), IntlDateFormatter::RELATIVE_MEDIUM, IntlDateFormatter::LONG, 'tomorrow, 12:00:00 AM UTC'],
560571
[strtotime('+1 day', time()), IntlDateFormatter::RELATIVE_SHORT, IntlDateFormatter::SHORT, 'tomorrow, 12:00 AM'],
561572
];

0 commit comments

Comments
 (0)