From d265739f7d659fab5fbbf86a146c87955f5bf682 Mon Sep 17 00:00:00 2001 From: Andrew Nicols Date: Wed, 20 Mar 2024 14:15:26 +0800 Subject: [PATCH] MDL-81074 core: Add assertTimeStringMatches PHPUnit Assertion Also raised as https://github.com/sebastianbergmann/phpunit/issues/5757 --- lib/phpunit/classes/base_testcase.php | 25 +++++++++ lib/phpunit/tests/basic_test.php | 78 +++++++++++++++++++++++++++ 2 files changed, 103 insertions(+) diff --git a/lib/phpunit/classes/base_testcase.php b/lib/phpunit/classes/base_testcase.php index 1ce5e56db0eb0..3ef4aa5cc0462 100644 --- a/lib/phpunit/classes/base_testcase.php +++ b/lib/phpunit/classes/base_testcase.php @@ -121,6 +121,31 @@ public static function assertValidKeys(array $hash, array $validKeys) { return $hash; } + /** + * Assert that two Date/Time strings are equal. + * + * The strings generated by \DateTime, \strtotime, \date, \time, etc. are generated outside of our control. + * From time-to-time string changes are made. + * One such example is from ICU 72.1 which changed the time format to include a narrow-non-breaking-space (U+202F) + * between the time and AM/PM. + * + * We should not update our tests to match these changes, as it is not our code that is + * generating the strings and they may change again. + * In addition, the changes are not equal amongst all systems as they depend on the version of ICU installed. + * + * @param string $expected + * @param string $actual + * @param string $message + */ + public function assertEqualsIgnoringWhitespace($expected, $actual, string $message = ''): void { + // ICU 72.1 introduced the use of a narrow-non-breaking-space (U+202F) between the time and the AM/PM. + // Normalise all whitespace when performing the comparison. + $expected = preg_replace('/\s+/u', ' ', $expected); + $actual = preg_replace('/\s+/u', ' ', $actual); + + $this->assertEquals($expected, $actual, $message); + } + /** * Parse out the options from the tag using DOM object tree. * diff --git a/lib/phpunit/tests/basic_test.php b/lib/phpunit/tests/basic_test.php index 190807b17c61f..88ab7bd6ecb18 100644 --- a/lib/phpunit/tests/basic_test.php +++ b/lib/phpunit/tests/basic_test.php @@ -145,6 +145,84 @@ public function test_assert_tag() { self::assertTag(['id' => 'testid'], "
"); } + /** + * Tests for assertEqualsIgnoringWhitespace. + * + * @param string $expected + * @param string $actual + * @param bool $expectationvalid + * @dataProvider equals_ignoring_whitespace_provider + */ + public function test_assertEqualsIgnoringWhitespace( // phpcs:ignore + string $expected, + string $actual, + bool $expectationvalid, + ): void { + if (!$expectationvalid) { + $this->expectException(\PHPUnit\Framework\ExpectationFailedException::class); + } + self::assertEqualsIgnoringWhitespace($expected, $actual); + } + + /** + * Data provider for assertEqualsIgnoringWhitespace tests + * + * @return array + */ + public static function equals_ignoring_whitespace_provider(): array { + return [ + 'equal' => ['a b c', 'a b c', true], + 'equal with whitespace' => ["a b c", "a\nb c", true], + 'equal with extra whitespace' => ["a b c", "a\nb c", true], + 'whitespace missing' => ["ab c", "a\nb c", false], + 'not equal' => ['a b c', 'a b d', false], + 'various space types' => [ + implode(' ', [ + '20', // Regular space. + "a0", // No-Break Space (NBSP). + "80", // Ogham Space Mark. + "0", // En Quad. + "1", // Em Quad. + "2", // En Space. + "3", // Em Space. + "4", // Three-Per-Em Space. + "5", // Four-Per-Em Space. + "6", // Six-Per-Em Space. + "7", // Figure Space. + "8", // Punctuation Space. + "9", // Thin Space. + "0a", // Hair Space. + "2f", // Narrow No-Break Space (NNBSP). + "5f", // Medium Mathematical Space. + "3000", // Ideographic Space. + ".", + ]), + implode('', [ + // All space chars taken from https://www.compart.com/en/unicode/category/Zs. + "20\u{0020}", // Regular space. + "a0\u{00a0}", // No-Break Space (NBSP). + "80\u{1680}", // Ogham Space Mark. + "0\u{2000}", // En Quad. + "1\u{2001}", // Em Quad. + "2\u{2002}", // En Space. + "3\u{2003}", // Em Space. + "4\u{2004}", // Three-Per-Em Space. + "5\u{2005}", // Four-Per-Em Space. + "6\u{2006}", // Six-Per-Em Space. + "7\u{2007}", // Figure Space. + "8\u{2008}", // Punctuation Space. + "9\u{2009}", // Thin Space. + "0a\u{200a}", // Hair Space. + "2f\u{202f}", // Narrow No-Break Space (NNBSP). + "5f\u{205f}", // Medium Mathematical Space. + "3000\u{3000}", // Ideographic Space. + ".", + ]), + true, + ], + ]; + } + // Uncomment following tests to see logging of unexpected changes in global state and database. /* public function test_db_modification() {