33use PHPUnit \Framework \TestCase ;
44
55class WP_PDO_MySQL_On_SQLite_PDO_API_Tests extends TestCase {
6- /**
7- * On PHP < 8.1, some PDO behavior is notably different from PHP >= 8.1.
8- * To address that, we need to use conditional assertions in some cases.
9- */
10- const LEGACY_PDO = PHP_VERSION_ID < 80100 ;
11-
126 /** @var WP_PDO_MySQL_On_SQLite */
137 private $ driver ;
148
159 public function setUp (): void {
1610 $ this ->driver = new WP_PDO_MySQL_On_SQLite ( 'mysql-on-sqlite:path=:memory:;dbname=wp; ' );
11+
12+ // Run all tests with stringified fetch mode results, so we can use
13+ // assertions that are consistent across all tested PHP versions.
14+ // The "PDO::ATTR_STRINGIFY_FETCHES" mode is tested in separately.
15+ $ this ->driver ->setAttribute ( PDO ::ATTR_STRINGIFY_FETCHES , true );
1716 }
1817
1918 public function test_connection (): void {
@@ -46,7 +45,7 @@ public function test_dsn_parsing(): void {
4645 public function test_query (): void {
4746 $ result = $ this ->driver ->query ( "SELECT 1, 'abc' " );
4847 $ this ->assertInstanceOf ( PDOStatement::class, $ result );
49- if ( self :: LEGACY_PDO ) {
48+ if ( PHP_VERSION_ID < 80000 ) {
5049 $ this ->assertSame (
5150 array (
5251 1 => '1 ' ,
@@ -59,8 +58,8 @@ public function test_query(): void {
5958 } else {
6059 $ this ->assertSame (
6160 array (
62- 1 => 1 ,
63- 0 => 1 ,
61+ 1 => ' 1 ' ,
62+ 0 => ' 1 ' ,
6463 'abc ' => 'abc ' ,
6564 ),
6665 $ result ->fetch ()
@@ -92,7 +91,7 @@ public function test_query_with_fetch_mode( $query, $mode, $expected ): void {
9291
9392 public function test_query_fetch_mode_not_set (): void {
9493 $ result = $ this ->driver ->query ( 'SELECT 1 ' );
95- if ( self :: LEGACY_PDO ) {
94+ if ( PHP_VERSION_ID < 80000 ) {
9695 $ this ->assertSame (
9796 array (
9897 1 => '1 ' ,
@@ -103,8 +102,8 @@ public function test_query_fetch_mode_not_set(): void {
103102 } else {
104103 $ this ->assertSame (
105104 array (
106- 1 => 1 ,
107- 0 => 1 ,
105+ 1 => ' 1 ' ,
106+ 0 => ' 1 ' ,
108107 ),
109108 $ result ->fetch ()
110109 );
@@ -119,7 +118,7 @@ public function test_query_fetch_mode_invalid_arg_count(): void {
119118 }
120119
121120 public function test_query_fetch_default_mode_allow_any_args (): void {
122- if ( self :: LEGACY_PDO ) {
121+ if ( PHP_VERSION_ID < 80100 ) {
123122 // On PHP < 8.1, fetch mode value of NULL is not allowed.
124123 $ result = @$ this ->driver ->query ( 'SELECT 1 ' , null , 1 , 2 , 'abc ' , array (), true ); // phpcs:ignore WordPress.PHP.NoSilencedErrors.Discouraged
125124 $ this ->assertFalse ( $ result );
@@ -131,8 +130,8 @@ public function test_query_fetch_default_mode_allow_any_args(): void {
131130 // In such cases, any additional arguments are ignored and not validated.
132131 $ expected_result = array (
133132 array (
134- 1 => 1 ,
135- 0 => 1 ,
133+ 1 => ' 1 ' ,
134+ 0 => ' 1 ' ,
136135 ),
137136 );
138137
@@ -269,7 +268,7 @@ public function test_rollback_no_active_transaction(): void {
269268 public function test_fetch_default (): void {
270269 // Default fetch mode is PDO::FETCH_BOTH.
271270 $ result = $ this ->driver ->query ( "SELECT 1, 'abc', 2 " );
272- if ( self :: LEGACY_PDO ) {
271+ if ( PHP_VERSION_ID < 80000 ) {
273272 $ this ->assertSame (
274273 array (
275274 1 => '1 ' ,
@@ -283,10 +282,10 @@ public function test_fetch_default(): void {
283282 } else {
284283 $ this ->assertSame (
285284 array (
286- 1 => 1 ,
287- 0 => 1 ,
285+ 1 => ' 1 ' ,
286+ 0 => ' 1 ' ,
288287 'abc ' => 'abc ' ,
289- '2 ' => 2 ,
288+ '2 ' => ' 2 ' ,
290289 ),
291290 $ result ->fetch ()
292291 );
@@ -333,12 +332,39 @@ public function test_attr_default_fetch_mode(): void {
333332 );
334333 }
335334
335+ public function test_attr_stringify_fetches (): void {
336+ $ this ->driver ->setAttribute ( PDO ::ATTR_STRINGIFY_FETCHES , true );
337+ $ result = $ this ->driver ->query ( "SELECT 123, 1.23, 'abc', true, false " );
338+ $ this ->assertSame (
339+ array ( '123 ' , '1.23 ' , 'abc ' , '1 ' , '0 ' ),
340+ $ result ->fetch ( PDO ::FETCH_NUM )
341+ );
342+
343+ $ this ->driver ->setAttribute ( PDO ::ATTR_STRINGIFY_FETCHES , false );
344+ $ result = $ this ->driver ->query ( "SELECT 123, 1.23, 'abc', true, false " );
345+ $ this ->assertSame (
346+ /*
347+ * On PHP < 8.1, "PDO::ATTR_STRINGIFY_FETCHES" set to "false" has no
348+ * effect when "PDO::ATTR_EMULATE_PREPARES" is "true" (the default).
349+ *
350+ * TODO: Consider supporting non-string values on PHP < 8.1 when both
351+ * "PDO::ATTR_STRINGIFY_FETCHES" and "PDO::ATTR_EMULATE_PREPARES"
352+ * are set to "false". This would require emulating the behavior,
353+ * as PDO SQLite on PHP < 8.1 seems to always return strings.
354+ */
355+ PHP_VERSION_ID < 80100
356+ ? array ( '123 ' , '1.23 ' , 'abc ' , '1 ' , '0 ' )
357+ : array ( 123 , 1.23 , 'abc ' , 1 , 0 ),
358+ $ result ->fetch ( PDO ::FETCH_NUM )
359+ );
360+ }
361+
336362 public function data_pdo_fetch_methods (): Generator {
337363 // PDO::FETCH_BOTH
338364 yield 'PDO::FETCH_BOTH ' => array (
339365 "SELECT 1, 'abc', 2, 'two' as `2` " ,
340366 PDO ::FETCH_BOTH ,
341- self :: LEGACY_PDO
367+ PHP_VERSION_ID < 80000
342368 ? array (
343369 1 => '1 ' ,
344370 2 => 'two ' ,
@@ -348,8 +374,8 @@ public function data_pdo_fetch_methods(): Generator {
348374 5 => 'two ' ,
349375 )
350376 : array (
351- 1 => 1 ,
352- 0 => 1 ,
377+ 1 => ' 1 ' ,
378+ 0 => ' 1 ' ,
353379 'abc ' => 'abc ' ,
354380 2 => 'two ' ,
355381 3 => 'two ' ,
@@ -360,17 +386,15 @@ public function data_pdo_fetch_methods(): Generator {
360386 yield 'PDO::FETCH_NUM ' => array (
361387 "SELECT 1, 'abc', 2, 'two' as `2` " ,
362388 PDO ::FETCH_NUM ,
363- self ::LEGACY_PDO
364- ? array ( '1 ' , 'abc ' , '2 ' , 'two ' )
365- : array ( 1 , 'abc ' , 2 , 'two ' ),
389+ array ( '1 ' , 'abc ' , '2 ' , 'two ' ),
366390 );
367391
368392 // PDO::FETCH_ASSOC
369393 yield 'PDO::FETCH_ASSOC ' => array (
370394 "SELECT 1, 'abc', 2, 'two' as `2` " ,
371395 PDO ::FETCH_ASSOC ,
372396 array (
373- 1 => self :: LEGACY_PDO ? '1 ' : 1 ,
397+ 1 => '1 ' ,
374398 'abc ' => 'abc ' ,
375399 2 => 'two ' ,
376400 ),
@@ -381,9 +405,9 @@ public function data_pdo_fetch_methods(): Generator {
381405 "SELECT 1, 'abc', 2, 'two' as `2` " ,
382406 PDO ::FETCH_NAMED ,
383407 array (
384- 1 => self :: LEGACY_PDO ? '1 ' : 1 ,
408+ 1 => '1 ' ,
385409 'abc ' => 'abc ' ,
386- 2 => array ( self :: LEGACY_PDO ? '2 ' : 2 , 'two ' ),
410+ 2 => array ( '2 ' , 'two ' ),
387411 ),
388412 );
389413
@@ -392,7 +416,7 @@ public function data_pdo_fetch_methods(): Generator {
392416 "SELECT 1, 'abc', 2, 'two' as `2` " ,
393417 PDO ::FETCH_OBJ ,
394418 (object ) array (
395- 1 => self :: LEGACY_PDO ? '1 ' : 1 ,
419+ 1 => '1 ' ,
396420 'abc ' => 'abc ' ,
397421 2 => 'two ' ,
398422 ),
0 commit comments