From 4aff8dcd85b59994d02b4d3be4f33b31b5f555c7 Mon Sep 17 00:00:00 2001 From: memleakd <121398829+memleakd@users.noreply.github.com> Date: Thu, 11 Jun 2026 11:16:47 +0200 Subject: [PATCH 1/3] test: add SQL equality assertion helper - Add assertSqlEquals() to CIUnitTestCase - Document the helper in the testing guide - Use the helper in representative Query Builder tests Signed-off-by: memleakd <121398829+memleakd@users.noreply.github.com> --- system/Test/CIUnitTestCase.php | 8 ++++++++ tests/system/Database/Builder/DeleteTest.php | 2 +- tests/system/Database/Builder/PrefixTest.php | 6 +++--- tests/system/Test/TestCaseTest.php | 11 +++++++++++ user_guide_src/source/changelogs/v4.8.0.rst | 2 ++ user_guide_src/source/testing/overview.rst | 7 +++++++ user_guide_src/source/testing/overview/023.php | 6 ++++++ 7 files changed, 38 insertions(+), 4 deletions(-) create mode 100644 user_guide_src/source/testing/overview/023.php diff --git a/system/Test/CIUnitTestCase.php b/system/Test/CIUnitTestCase.php index edfa98df5c06..09b8ac80075d 100644 --- a/system/Test/CIUnitTestCase.php +++ b/system/Test/CIUnitTestCase.php @@ -501,6 +501,14 @@ public function assertCloseEnoughString($expected, $actual, string $message = '' return null; } + /** + * Asserts that two SQL strings are the same, ignoring newlines in the actual SQL. + */ + public function assertSqlEquals(string $expected, string $actual, string $message = ''): void + { + $this->assertSame($expected, str_replace("\n", ' ', $actual), $message); + } + // -------------------------------------------------------------------- // Utility // -------------------------------------------------------------------- diff --git a/tests/system/Database/Builder/DeleteTest.php b/tests/system/Database/Builder/DeleteTest.php index 53b66eed805b..0cd05dcd4168 100644 --- a/tests/system/Database/Builder/DeleteTest.php +++ b/tests/system/Database/Builder/DeleteTest.php @@ -46,7 +46,7 @@ public function testDelete(): void ], ]; - $this->assertSame($expectedSQL, str_replace("\n", ' ', $answer)); + $this->assertSqlEquals($expectedSQL, $answer); $this->assertSame($expectedBinds, $builder->getBinds()); } diff --git a/tests/system/Database/Builder/PrefixTest.php b/tests/system/Database/Builder/PrefixTest.php index 44d405ce7643..98204c31edc5 100644 --- a/tests/system/Database/Builder/PrefixTest.php +++ b/tests/system/Database/Builder/PrefixTest.php @@ -51,7 +51,7 @@ public function testPrefixesSetOnTableNamesWithWhereClause(): void $builder->where($where); - $this->assertSame($expectedSQL, str_replace("\n", ' ', $builder->getCompiledSelect())); + $this->assertSqlEquals($expectedSQL, $builder->getCompiledSelect()); $this->assertSame($expectedBinds, $builder->getBinds()); } @@ -64,7 +64,7 @@ public function testPrefixesSetOnTableNamesWithWhereColumnClause(): void $builder->whereColumn('users.created_at <', 'users.updated_at'); - $this->assertSame($expectedSQL, str_replace("\n", ' ', $builder->getCompiledSelect())); + $this->assertSqlEquals($expectedSQL, $builder->getCompiledSelect()); $this->assertSame($expectedBinds, $builder->getBinds()); } @@ -86,7 +86,7 @@ public function testPrefixesSetOnTableNamesWithWhereBetweenClause(): void $builder->whereBetween('users.created_at', [1, 10]); - $this->assertSame($expectedSQL, str_replace("\n", ' ', $builder->getCompiledSelect())); + $this->assertSqlEquals($expectedSQL, $builder->getCompiledSelect()); $this->assertSame($expectedBinds, $builder->getBinds()); } diff --git a/tests/system/Test/TestCaseTest.php b/tests/system/Test/TestCaseTest.php index 6905d825533a..d60c0ef4eef9 100644 --- a/tests/system/Test/TestCaseTest.php +++ b/tests/system/Test/TestCaseTest.php @@ -93,4 +93,15 @@ public function testCloseEnoughStringBadLength(): void $result = $this->assertCloseEnoughString('apples & oranges', 'apples'); $this->assertFalse($result, 'Different string lengths should have returned false'); } + + public function testAssertSqlEqualsIgnoresNewlinesInActualSql(): void + { + $expected = 'SELECT * FROM "jobs" WHERE "id" = 1'; + $actual = <<<'SQL' + SELECT * FROM "jobs" + WHERE "id" = 1 + SQL; + + $this->assertSqlEquals($expected, $actual); + } } diff --git a/user_guide_src/source/changelogs/v4.8.0.rst b/user_guide_src/source/changelogs/v4.8.0.rst index 54083bdbb925..834af1e3fe5e 100644 --- a/user_guide_src/source/changelogs/v4.8.0.rst +++ b/user_guide_src/source/changelogs/v4.8.0.rst @@ -213,6 +213,8 @@ Commands Testing ======= +- Added ``assertSqlEquals()`` to ``CIUnitTestCase`` to compare generated SQL while ignoring newlines in the actual SQL. + Database ======== diff --git a/user_guide_src/source/testing/overview.rst b/user_guide_src/source/testing/overview.rst index 4d49c5569355..b2354c6a7cec 100644 --- a/user_guide_src/source/testing/overview.rst +++ b/user_guide_src/source/testing/overview.rst @@ -202,6 +202,13 @@ between expected and actual time, formatted as strings, is within the prescribed The above test will allow the actual time to be either 660 or 661 seconds. +assertSqlEquals($expected, $actual, $message = '') +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +Asserts that two SQL strings are the same, ignoring newlines in the actual SQL: + +.. literalinclude:: overview/023.php + Accessing Protected/Private Properties -------------------------------------- diff --git a/user_guide_src/source/testing/overview/023.php b/user_guide_src/source/testing/overview/023.php new file mode 100644 index 000000000000..6fdf03213405 --- /dev/null +++ b/user_guide_src/source/testing/overview/023.php @@ -0,0 +1,6 @@ +where('id', 1)->getCompiledSelect(); + +$this->assertSqlEquals($expected, $actual); From 47b3b024c8dfbf9e68aac8f9cc6e44de5d7d61f1 Mon Sep 17 00:00:00 2001 From: memleakd <121398829+memleakd@users.noreply.github.com> Date: Thu, 11 Jun 2026 19:50:50 +0200 Subject: [PATCH 2/3] rename SQL assertion helper Signed-off-by: memleakd <121398829+memleakd@users.noreply.github.com> --- system/Test/CIUnitTestCase.php | 2 +- tests/system/Database/Builder/DeleteTest.php | 2 +- tests/system/Database/Builder/PrefixTest.php | 6 +++--- tests/system/Test/TestCaseTest.php | 4 ++-- user_guide_src/source/changelogs/v4.8.0.rst | 2 +- user_guide_src/source/testing/overview.rst | 4 ++-- user_guide_src/source/testing/overview/023.php | 2 +- 7 files changed, 11 insertions(+), 11 deletions(-) diff --git a/system/Test/CIUnitTestCase.php b/system/Test/CIUnitTestCase.php index 09b8ac80075d..091c17eae981 100644 --- a/system/Test/CIUnitTestCase.php +++ b/system/Test/CIUnitTestCase.php @@ -504,7 +504,7 @@ public function assertCloseEnoughString($expected, $actual, string $message = '' /** * Asserts that two SQL strings are the same, ignoring newlines in the actual SQL. */ - public function assertSqlEquals(string $expected, string $actual, string $message = ''): void + public function assertSameSql(string $expected, string $actual, string $message = ''): void { $this->assertSame($expected, str_replace("\n", ' ', $actual), $message); } diff --git a/tests/system/Database/Builder/DeleteTest.php b/tests/system/Database/Builder/DeleteTest.php index 0cd05dcd4168..59c776b90804 100644 --- a/tests/system/Database/Builder/DeleteTest.php +++ b/tests/system/Database/Builder/DeleteTest.php @@ -46,7 +46,7 @@ public function testDelete(): void ], ]; - $this->assertSqlEquals($expectedSQL, $answer); + $this->assertSameSql($expectedSQL, $answer); $this->assertSame($expectedBinds, $builder->getBinds()); } diff --git a/tests/system/Database/Builder/PrefixTest.php b/tests/system/Database/Builder/PrefixTest.php index 98204c31edc5..dcd58a46e035 100644 --- a/tests/system/Database/Builder/PrefixTest.php +++ b/tests/system/Database/Builder/PrefixTest.php @@ -51,7 +51,7 @@ public function testPrefixesSetOnTableNamesWithWhereClause(): void $builder->where($where); - $this->assertSqlEquals($expectedSQL, $builder->getCompiledSelect()); + $this->assertSameSql($expectedSQL, $builder->getCompiledSelect()); $this->assertSame($expectedBinds, $builder->getBinds()); } @@ -64,7 +64,7 @@ public function testPrefixesSetOnTableNamesWithWhereColumnClause(): void $builder->whereColumn('users.created_at <', 'users.updated_at'); - $this->assertSqlEquals($expectedSQL, $builder->getCompiledSelect()); + $this->assertSameSql($expectedSQL, $builder->getCompiledSelect()); $this->assertSame($expectedBinds, $builder->getBinds()); } @@ -86,7 +86,7 @@ public function testPrefixesSetOnTableNamesWithWhereBetweenClause(): void $builder->whereBetween('users.created_at', [1, 10]); - $this->assertSqlEquals($expectedSQL, $builder->getCompiledSelect()); + $this->assertSameSql($expectedSQL, $builder->getCompiledSelect()); $this->assertSame($expectedBinds, $builder->getBinds()); } diff --git a/tests/system/Test/TestCaseTest.php b/tests/system/Test/TestCaseTest.php index d60c0ef4eef9..8214574d0b8a 100644 --- a/tests/system/Test/TestCaseTest.php +++ b/tests/system/Test/TestCaseTest.php @@ -94,7 +94,7 @@ public function testCloseEnoughStringBadLength(): void $this->assertFalse($result, 'Different string lengths should have returned false'); } - public function testAssertSqlEqualsIgnoresNewlinesInActualSql(): void + public function testAssertSameSqlIgnoresNewlinesInActualSql(): void { $expected = 'SELECT * FROM "jobs" WHERE "id" = 1'; $actual = <<<'SQL' @@ -102,6 +102,6 @@ public function testAssertSqlEqualsIgnoresNewlinesInActualSql(): void WHERE "id" = 1 SQL; - $this->assertSqlEquals($expected, $actual); + $this->assertSameSql($expected, $actual); } } diff --git a/user_guide_src/source/changelogs/v4.8.0.rst b/user_guide_src/source/changelogs/v4.8.0.rst index 834af1e3fe5e..614562d2991b 100644 --- a/user_guide_src/source/changelogs/v4.8.0.rst +++ b/user_guide_src/source/changelogs/v4.8.0.rst @@ -213,7 +213,7 @@ Commands Testing ======= -- Added ``assertSqlEquals()`` to ``CIUnitTestCase`` to compare generated SQL while ignoring newlines in the actual SQL. +- Added ``assertSameSql()`` to ``CIUnitTestCase`` to compare generated SQL while ignoring newlines in the actual SQL. Database ======== diff --git a/user_guide_src/source/testing/overview.rst b/user_guide_src/source/testing/overview.rst index b2354c6a7cec..b00cbb8539d7 100644 --- a/user_guide_src/source/testing/overview.rst +++ b/user_guide_src/source/testing/overview.rst @@ -202,8 +202,8 @@ between expected and actual time, formatted as strings, is within the prescribed The above test will allow the actual time to be either 660 or 661 seconds. -assertSqlEquals($expected, $actual, $message = '') -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +assertSameSql($expected, $actual, $message = '') +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Asserts that two SQL strings are the same, ignoring newlines in the actual SQL: diff --git a/user_guide_src/source/testing/overview/023.php b/user_guide_src/source/testing/overview/023.php index 6fdf03213405..32c126ca780b 100644 --- a/user_guide_src/source/testing/overview/023.php +++ b/user_guide_src/source/testing/overview/023.php @@ -3,4 +3,4 @@ $expected = 'SELECT * FROM "jobs" WHERE "id" = 1'; $actual = $builder->where('id', 1)->getCompiledSelect(); -$this->assertSqlEquals($expected, $actual); +$this->assertSameSql($expected, $actual); From 54dd791ef4070e95105bd039c6a9a97e54b4b0f6 Mon Sep 17 00:00:00 2001 From: memleakd <121398829+memleakd@users.noreply.github.com> Date: Thu, 11 Jun 2026 20:38:25 +0200 Subject: [PATCH 3/3] test: support CRLF in SQL assertions Signed-off-by: memleakd <121398829+memleakd@users.noreply.github.com> --- system/Test/CIUnitTestCase.php | 2 +- tests/system/Test/TestCaseTest.php | 8 ++++++++ 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/system/Test/CIUnitTestCase.php b/system/Test/CIUnitTestCase.php index 091c17eae981..468f216079d4 100644 --- a/system/Test/CIUnitTestCase.php +++ b/system/Test/CIUnitTestCase.php @@ -506,7 +506,7 @@ public function assertCloseEnoughString($expected, $actual, string $message = '' */ public function assertSameSql(string $expected, string $actual, string $message = ''): void { - $this->assertSame($expected, str_replace("\n", ' ', $actual), $message); + $this->assertSame($expected, str_replace(["\r\n", "\r", "\n"], ' ', $actual), $message); } // -------------------------------------------------------------------- diff --git a/tests/system/Test/TestCaseTest.php b/tests/system/Test/TestCaseTest.php index 8214574d0b8a..893caaa9119d 100644 --- a/tests/system/Test/TestCaseTest.php +++ b/tests/system/Test/TestCaseTest.php @@ -104,4 +104,12 @@ public function testAssertSameSqlIgnoresNewlinesInActualSql(): void $this->assertSameSql($expected, $actual); } + + public function testAssertSameSqlIgnoresCrLfInActualSql(): void + { + $expected = 'SELECT * FROM "jobs" WHERE "id" = 1'; + $actual = "SELECT * FROM \"jobs\"\r\nWHERE \"id\" = 1"; + + $this->assertSameSql($expected, $actual); + } }