Repository: thephpleague/csv (language: php)

Issue:
Some tests failing when using XDEBUG_MODE=off - strtolower(): Argument #1 ($string) must be of type string, null given
## Bug Report

_(Fill in the relevant information below to help triage your issue.)_

| Information | Description |
|--------------|---------|
| Version | 9.22.0 |
| PHP version | 8.4.4 |
| OS Platform | debian trixie |

### Summary

While trying to find a workaround for #556 , I encountered 3 errors reported when running the tests with XDEBUG_MODE=off.
They look like deprecation warning due to a recent php version.

### Standalone code, or other way to reproduce the problem

Run

`XDEBUG_MODE=off phpunit --no-coverage`

### Expected result

No issue

### Actual result

```
$ XDEBUG_MODE=off phpunit --no-coverage
PHPUnit 11.5.8 by Sebastian Bergmann and contributors.

Runtime:       PHP 8.4.4
Configuration: /home/fabien/php-league-csv/phpunit.xml

.......E.......................................................  63 / 679 (  9%)
............................................................... 126 / 679 ( 18%)
...........DDDDD..............................E................ 189 / 679 ( 27%)
.....................................DDDDDDDDDDD............... 252 / 679 ( 37%)
............................................................... 315 / 679 ( 46%)
............................................................... 378 / 679 ( 55%)
............................................................... 441 / 679 ( 64%)
............................................................... 504 / 679 ( 74%)
............................................................... 567 / 679 ( 83%)
......................D........................................ 630 / 679 ( 92%)
sbb,one
.........................................E.......               679 / 679 (100%)

Time: 00:00.688, Memory: 16.00 MB

There were 3 errors:

1) League\Csv\AbstractCsvTest::testOutputHeaders
TypeError: strtolower(): Argument #1 ($string) must be of type string, null given

/home/fabien/php-league-csv/src/AbstractCsvTest.php:143

2) League\Csv\JsonConverterTest::it_can_make_the_generated_json_downloadable_ont_the_fly
TypeError: strtolower(): Argument #1 ($string) must be of type string, null given

/home/fabien/php-league-csv/src/JsonConverterTest.php:150

3) League\Csv\XMLConverterTest::testDownload
TypeError: strtolower(): Argument #1 ($string) must be of type string, null given

/home/fabien/php-league-csv/src/XMLConverterTest.php:117

ERRORS!
Tests: 679, Assertions: 1171, Errors: 3, Warnings: 3, Deprecations: 16.
```



## Checks before submitting

* [x] Be sure that there isn't already an issue about this. See: [Issues list](https://github.com/thephpleague/csv/issues)
* [x] Be sure that there isn't already a pull request about this. See: [Pull requests](https://github.com/thephpleague/csv/pulls)
* [x] I have added every step to reproduce the bug.
* [ ] If possible I added relevant code examples.
* [x] This issue is about 1 bug and nothing more.
* [x] The issue has a descriptive title. For example:  "JSON rendering failed on Windows for filenames with space".



Discussion / hints:

Fix patch:
diff --git a/src/AbstractCsvTest.php b/src/AbstractCsvTest.php
index 70adcf5a..d8d470b6 100644
--- a/src/AbstractCsvTest.php
+++ b/src/AbstractCsvTest.php
@@ -23,6 +23,7 @@
 use function chr;
 use function fopen;
 use function function_exists;
+use function implode;
 use function ob_get_clean;
 use function ob_start;
 use function strtolower;
@@ -137,13 +138,17 @@ public function testOutputHeaders(): void
         $csv->download('tést.csv');
         ob_end_clean();
         $headers = xdebug_get_headers();
+        if ([] === $headers) {
+            self::markTestSkipped(__METHOD__.' needs the xdebug function `xdebug_get_headers` to run and returns actual data.');
+        }
+        $header = implode("\n", $headers);
 
         // Due to the variety of ways the xdebug expresses Content-Type of text files,
         // we cannot count on complete string matching.
-        self::assertStringContainsString('content-type: text/csv', strtolower($headers[0]));
-        self::assertSame('content-transfer-encoding: binary', strtolower($headers[1]));
-        self::assertSame('content-description: File Transfer', $headers[2]);
-        self::assertStringContainsString('content-disposition: attachment;filename="tst.csv";filename*=UTF-8\'\'t%c3%a9st.csv', $headers[3]);
+        self::assertStringContainsString('content-type: text/csv', strtolower($header));
+        self::assertStringContainsString('content-transfer-encoding: binary', strtolower($header));
+        self::assertStringContainsString('content-description: File Transfer', $header);
+        self::assertStringContainsString('content-disposition: attachment;filename="tst.csv";filename*=UTF-8\'\'t%c3%a9st.csv', $header);
     }
 
     public function testChunkDoesNotTimeoutAfterReading(): void
diff --git a/src/JsonConverterTest.php b/src/JsonConverterTest.php
index 0e2c2d9e..571767c1 100644
--- a/src/JsonConverterTest.php
+++ b/src/JsonConverterTest.php
@@ -21,6 +21,9 @@
 use RuntimeException;
 use TypeError;
 
+use function implode;
+use function xdebug_get_headers;
+
 use const JSON_FORCE_OBJECT;
 use const JSON_HEX_QUOT;
 use const JSON_PRETTY_PRINT;
@@ -144,13 +147,17 @@ public function it_can_make_the_generated_json_downloadable_ont_the_fly(): void
         (new JsonConverter())->download([['foo' => 'bar']], 'foobar.json');
         $output = ob_get_clean();
         $headers = xdebug_get_headers();
+        if ([] === $headers) {
+            self::markTestSkipped(__METHOD__.' needs the xdebug function `xdebug_get_headers` to run and returns actual data.');
+        }
+        $header = implode("\n", $headers);
 
         // Due to the variety of ways the xdebug expresses Content-Type of text files,
         // we cannot count on complete string matching.
-        self::assertStringContainsString('content-type: application/json', strtolower($headers[0]));
-        self::assertSame('content-transfer-encoding: binary', strtolower($headers[1]));
-        self::assertSame('content-description: File Transfer', $headers[2]);
-        self::assertStringContainsString('content-disposition: attachment;filename="foobar.json"', $headers[3]);
+        self::assertStringContainsString('content-type: application/json', strtolower($header));
+        self::assertStringContainsString('content-transfer-encoding: binary', strtolower($header));
+        self::assertStringContainsString('content-description: File Transfer', $header);
+        self::assertStringContainsString('content-disposition: attachment;filename="foobar.json"', $header);
         self::assertSame('[{"foo":"bar"}]', $output);
     }
 
diff --git a/src/XMLConverterTest.php b/src/XMLConverterTest.php
index 9ee5ed57..01100ff4 100644
--- a/src/XMLConverterTest.php
+++ b/src/XMLConverterTest.php
@@ -24,6 +24,8 @@
 
 use function array_map;
 use function class_exists;
+use function implode;
+use function xdebug_get_headers;
 
 #[Group('converter')]
 final class XMLConverterTest extends TestCase
@@ -111,14 +113,16 @@ public function testDownload(): void
         (new XMLConverter())->fieldElement('cell', 'name')->download([['foo' => 'bar']], 'foobar.xml');
         $output = (string) ob_get_clean();
         $headers = xdebug_get_headers();
+        if ([] === $headers) {
+            self::markTestSkipped(__METHOD__.' needs the xdebug function `xdebug_get_headers` to run and returns actual data.');
+        }
+        $header = implode("\n", $headers);
 
-        $xml = '<csv><row><cell name="foo">bar</cell></row></csv>';
-
-        self::assertStringContainsString('content-type: application/xml', strtolower($headers[0]));
-        self::assertSame('content-transfer-encoding: binary', strtolower($headers[1]));
-        self::assertSame('content-description: File Transfer', $headers[2]);
-        self::assertStringContainsString('content-disposition: attachment;filename="foobar.xml"', $headers[3]);
-        self::assertStringContainsString($xml, $output);
+        self::assertStringContainsString('content-type: application/xml', strtolower($header));
+        self::assertStringContainsString('content-transfer-encoding: binary', strtolower($header));
+        self::assertStringContainsString('content-description: File Transfer', $header);
+        self::assertStringContainsString('content-disposition: attachment;filename="foobar.xml"', $header);
+        self::assertStringContainsString('<csv><row><cell name="foo">bar</cell></row></csv>', $output);
     }
 
     public function testToXMLWithFormatter(): void


Test patch: