From 28ea7599912b0ce6c99cd0bf7b0a2c0cded00c7d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Elan=20Ruusam=C3=A4e?= Date: Mon, 7 Dec 2020 14:44:51 +0200 Subject: [PATCH 1/5] Add constant for Non-breaking space UTF-8 encoded value This is to clearly indicate specific encoding is expected --- tests/Zend/Locale/FormatTest.php | 8 +++++++- tests/Zend/Validate/FloatTest.php | 8 +++++++- 2 files changed, 14 insertions(+), 2 deletions(-) diff --git a/tests/Zend/Locale/FormatTest.php b/tests/Zend/Locale/FormatTest.php index 39ac8f790..22aee5f1e 100644 --- a/tests/Zend/Locale/FormatTest.php +++ b/tests/Zend/Locale/FormatTest.php @@ -35,6 +35,12 @@ */ class Zend_Locale_FormatTest extends PHPUnit_Framework_TestCase { + /** + * Constant for Non-breaking space UTF-8 encoded value. + * https://en.wikipedia.org/wiki/Non-breaking_space + */ + const NBSP = " "; + /** * teardown / cleanup */ @@ -944,7 +950,7 @@ public function testToFloatSetlocale() $myFloat = 1234.5; $test1 = Zend_Locale_Format::toFloat($myFloat, $params_fr); $test2 = Zend_Locale_Format::toFloat($myFloat, $params_en); - $this->assertEquals("1 234,50", $test1); + $this->assertEquals("1" . self::NBSP . "234,50", $test1); $this->assertEquals("1,234.50", $test2); // placing tearDown here (i.e. restoring locale) won't work, if test already failed/aborted above. } diff --git a/tests/Zend/Validate/FloatTest.php b/tests/Zend/Validate/FloatTest.php index 26a4386c8..d7e366aba 100644 --- a/tests/Zend/Validate/FloatTest.php +++ b/tests/Zend/Validate/FloatTest.php @@ -35,6 +35,12 @@ */ class Zend_Validate_FloatTest extends PHPUnit_Framework_TestCase { + /** + * Constant for Non-breaking space UTF-8 encoded value. + * https://en.wikipedia.org/wiki/Non-breaking_space + */ + const NBSP = " "; + /** * Zend_Validate_Float object * @@ -196,7 +202,7 @@ public function testPhpLocaleFrStringType() $valid = new Zend_Validate_Float('fr_FR'); $this->assertTrue($valid->isValid('1,3')); $this->assertTrue($valid->isValid('1000,3')); - $this->assertTrue($valid->isValid('1 000,3')); + $this->assertTrue($valid->isValid('1' . self::NBSP . '000,3')); $this->assertFalse($valid->isValid('1.3')); $this->assertFalse($valid->isValid('1000.3')); $this->assertFalse($valid->isValid('1,000.3')); From 3c5aa8c17266364e79f91ff25e0e11b866f5b522 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Elan=20Ruusam=C3=A4e?= Date: Tue, 12 Jan 2021 19:52:55 +0200 Subject: [PATCH 2/5] Restore locales before calling assertions This ensures global state like locale is restored before throwing exceptions. --- tests/Zend/Locale/FormatTest.php | 13 ++++++--- tests/Zend/Validate/FloatTest.php | 45 ++++++++++++++++++++++++------- 2 files changed, 44 insertions(+), 14 deletions(-) diff --git a/tests/Zend/Locale/FormatTest.php b/tests/Zend/Locale/FormatTest.php index 22aee5f1e..df739c907 100644 --- a/tests/Zend/Locale/FormatTest.php +++ b/tests/Zend/Locale/FormatTest.php @@ -940,9 +940,9 @@ public function testConvertPhpToIso() */ public function testToFloatSetlocale() { - setlocale(LC_ALL, 'fr_FR@euro'); // test setup + $locale = setlocale(LC_ALL, 0); + setlocale(LC_ALL, 'fr_FR@euro'); - //var_dump( setlocale(LC_NUMERIC, '0')); // this is the specific setting of interest $locale_fr = new Zend_Locale('fr_FR'); $locale_en = new Zend_Locale('en_US'); $params_fr = array('precision' => 2, 'locale' => $locale_fr); @@ -950,9 +950,11 @@ public function testToFloatSetlocale() $myFloat = 1234.5; $test1 = Zend_Locale_Format::toFloat($myFloat, $params_fr); $test2 = Zend_Locale_Format::toFloat($myFloat, $params_en); + + setlocale(LC_ALL, $locale); + $this->assertEquals("1" . self::NBSP . "234,50", $test1); $this->assertEquals("1,234.50", $test2); - // placing tearDown here (i.e. restoring locale) won't work, if test already failed/aborted above. } /** @@ -1114,10 +1116,13 @@ public function testToNumberWithoutFormatWithPrecision() public function testCheckDateFormatDoesNotEmitNoticeWhenNoOptionsAreNotProvided() { try { + $locale = setlocale(LC_ALL, 0); // read current locale setlocale(LC_ALL, 'en_US'); // test setup Zend_Locale_Format::setOptions(array('date_format' => 'yyyy-MM-dd')); + $checkDateFormat = Zend_Locale_Format::checkDateFormat('2011-10-21', array()); + setlocale(LC_ALL, $locale); // restore previous locale - $this->assertTrue(Zend_Locale_Format::checkDateFormat('2011-10-21', array())); + $this->assertTrue($checkDateFormat); } catch ( PHPUnit_Framework_Error_Notice $ex ) { $this->fail('Zend_Locale_Format::checkDateFormat emitted unexpected E_NOTICE'); } diff --git a/tests/Zend/Validate/FloatTest.php b/tests/Zend/Validate/FloatTest.php index d7e366aba..bb5245afb 100644 --- a/tests/Zend/Validate/FloatTest.php +++ b/tests/Zend/Validate/FloatTest.php @@ -48,6 +48,11 @@ class Zend_Validate_FloatTest extends PHPUnit_Framework_TestCase */ protected $_validator; + /** + * @var string + */ + private $_locale; + /** * Creates a new Zend_Validate_Float object for each test method * @@ -142,10 +147,14 @@ public function testUsingApplicationLocale() */ public function testNoZendLocaleButPhpLocale() { + $locale = setlocale(LC_ALL, 0); setlocale(LC_ALL, 'de'); $valid = new Zend_Validate_Float(); - $this->assertTrue($valid->isValid(123,456)); - $this->assertTrue($valid->isValid('123,456')); + $isValid1 = $valid->isValid(123.456); + $isValid2 = $valid->isValid('123,456'); + setlocale(LC_ALL, $locale); + $this->assertTrue($isValid1); + $this->assertTrue($isValid2); } /** @@ -163,9 +172,12 @@ public function testLocaleDeFloatType() */ public function testPhpLocaleDeFloatType() { + $locale = setlocale(LC_ALL, 0); setlocale(LC_ALL, 'de'); $valid = new Zend_Validate_Float(); - $this->assertTrue($valid->isValid(10.5)); + $isValid = $valid->isValid(10.5); + setlocale(LC_ALL, $locale); + $this->assertTrue($isValid); } /** @@ -173,9 +185,12 @@ public function testPhpLocaleDeFloatType() */ public function testPhpLocaleFrFloatType() { + $locale = setlocale(LC_ALL, 0); setlocale(LC_ALL, 'fr'); $valid = new Zend_Validate_Float(); - $this->assertTrue($valid->isValid(10.5)); + $isValid = $valid->isValid(10.5); + setlocale(LC_ALL, $locale); + $this->assertTrue($isValid); } /** @@ -183,15 +198,25 @@ public function testPhpLocaleFrFloatType() */ public function testPhpLocaleDeStringType() { + $lcAll = setlocale(LC_ALL, 0); setlocale(LC_ALL, 'de_AT'); + $lcNumeric = setlocale(LC_NUMERIC, 0); setlocale(LC_NUMERIC, 'de_AT'); $valid = new Zend_Validate_Float('de_AT'); - $this->assertTrue($valid->isValid('1,3')); - $this->assertTrue($valid->isValid('1000,3')); - $this->assertTrue($valid->isValid('1.000,3')); - $this->assertFalse($valid->isValid('1.3')); - $this->assertFalse($valid->isValid('1000.3')); - $this->assertFalse($valid->isValid('1,000.3')); + $isValid0 = $valid->isValid('1,3'); + $isValid1 = $valid->isValid('1000,3'); + $isValid2 = $valid->isValid('1.000,3'); + $isValid3 = $valid->isValid('1.3'); + $isValid4 = $valid->isValid('1000.3'); + $isValid5 = $valid->isValid('1,000.3'); + setlocale(LC_ALL, $lcAll); + setlocale(LC_NUMERIC, $lcNumeric); + $this->assertTrue($isValid0); + $this->assertTrue($isValid1); + $this->assertTrue($isValid2); + $this->assertFalse($isValid3); + $this->assertFalse($isValid4); + $this->assertFalse($isValid5); } /** From c2d35ce21d529a2e8ece629e93ec68c8595c990f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Elan=20Ruusam=C3=A4e?= Date: Tue, 12 Jan 2021 19:40:11 +0200 Subject: [PATCH 3/5] Enable locale testing in CI --- .github/workflows/tests.yml | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 352738be6..d831aaf88 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -34,6 +34,8 @@ jobs: MYSQL_PASSWORD: "zftest" MYSQL_DATABASE: "zftest" MYSQL_HOST: "127.0.0.1" + # Default locales are: C C.UTF-8 POSIX en_US.utf8 + LOCALES: "fr_FR@euro fr_FR fr_BE.UTF-8 de en_US" services: memcache: @@ -81,6 +83,11 @@ jobs: - name: Setup environment for PHPUnit run: | cp tests/TestConfiguration.ci.php tests/TestConfiguration.php + echo "Existing locales" + locale -a + sudo apt-get update && sudo apt-get install tzdata locales -y && sudo locale-gen $LOCALES + echo "All languages..." + locale -a - name: "Run PHPUnit tests (Experimental: ${{ matrix.experimental }})" env: From 4d0f80987b128e4c1f28b1f4b11f8122e661bea9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Elan=20Ruusam=C3=A4e?= Date: Mon, 15 Mar 2021 16:31:22 +0200 Subject: [PATCH 4/5] Use hex escape to define Non-breaking_space --- tests/Zend/Locale/FormatTest.php | 2 +- tests/Zend/Validate/FloatTest.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/Zend/Locale/FormatTest.php b/tests/Zend/Locale/FormatTest.php index df739c907..d42583581 100644 --- a/tests/Zend/Locale/FormatTest.php +++ b/tests/Zend/Locale/FormatTest.php @@ -39,7 +39,7 @@ class Zend_Locale_FormatTest extends PHPUnit_Framework_TestCase * Constant for Non-breaking space UTF-8 encoded value. * https://en.wikipedia.org/wiki/Non-breaking_space */ - const NBSP = " "; + const NBSP = "\xC2\xA0"; /** * teardown / cleanup diff --git a/tests/Zend/Validate/FloatTest.php b/tests/Zend/Validate/FloatTest.php index bb5245afb..e09ce128b 100644 --- a/tests/Zend/Validate/FloatTest.php +++ b/tests/Zend/Validate/FloatTest.php @@ -39,7 +39,7 @@ class Zend_Validate_FloatTest extends PHPUnit_Framework_TestCase * Constant for Non-breaking space UTF-8 encoded value. * https://en.wikipedia.org/wiki/Non-breaking_space */ - const NBSP = " "; + const NBSP = "\xC2\xA0"; /** * Zend_Validate_Float object From 938c6c2c8053c363b007dbfb546c590c82310a9c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Elan=20Ruusam=C3=A4e?= Date: Tue, 16 Mar 2021 09:41:26 +0200 Subject: [PATCH 5/5] Restore locale if exception is thrown --- tests/Zend/Locale/FormatTest.php | 40 ++++++++++++++++++++------------ 1 file changed, 25 insertions(+), 15 deletions(-) diff --git a/tests/Zend/Locale/FormatTest.php b/tests/Zend/Locale/FormatTest.php index d42583581..ef9f6fdc3 100644 --- a/tests/Zend/Locale/FormatTest.php +++ b/tests/Zend/Locale/FormatTest.php @@ -941,20 +941,28 @@ public function testConvertPhpToIso() public function testToFloatSetlocale() { $locale = setlocale(LC_ALL, 0); - setlocale(LC_ALL, 'fr_FR@euro'); - - $locale_fr = new Zend_Locale('fr_FR'); - $locale_en = new Zend_Locale('en_US'); - $params_fr = array('precision' => 2, 'locale' => $locale_fr); - $params_en = array('precision' => 2, 'locale' => $locale_en); - $myFloat = 1234.5; - $test1 = Zend_Locale_Format::toFloat($myFloat, $params_fr); - $test2 = Zend_Locale_Format::toFloat($myFloat, $params_en); - + try { + setlocale(LC_ALL, 'fr_FR@euro'); + + $locale_fr = new Zend_Locale('fr_FR'); + $locale_en = new Zend_Locale('en_US'); + $params_fr = array('precision' => 2, 'locale' => $locale_fr); + $params_en = array('precision' => 2, 'locale' => $locale_en); + $myFloat = 1234.5; + $test1 = Zend_Locale_Format::toFloat($myFloat, $params_fr); + $test2 = Zend_Locale_Format::toFloat($myFloat, $params_en); + + $this->assertEquals("1" . self::NBSP . "234,50", $test1); + $this->assertEquals("1,234.50", $test2); + + } catch (Exception $e) { + setlocale(LC_ALL, $locale); + throw $e; + } catch (Throwable $e) { + setlocale(LC_ALL, $locale); + throw $e; + } setlocale(LC_ALL, $locale); - - $this->assertEquals("1" . self::NBSP . "234,50", $test1); - $this->assertEquals("1,234.50", $test2); } /** @@ -1115,17 +1123,19 @@ public function testToNumberWithoutFormatWithPrecision() */ public function testCheckDateFormatDoesNotEmitNoticeWhenNoOptionsAreNotProvided() { + $locale = setlocale(LC_ALL, 0); // read current locale try { - $locale = setlocale(LC_ALL, 0); // read current locale setlocale(LC_ALL, 'en_US'); // test setup Zend_Locale_Format::setOptions(array('date_format' => 'yyyy-MM-dd')); $checkDateFormat = Zend_Locale_Format::checkDateFormat('2011-10-21', array()); - setlocale(LC_ALL, $locale); // restore previous locale $this->assertTrue($checkDateFormat); } catch ( PHPUnit_Framework_Error_Notice $ex ) { + setlocale(LC_ALL, $locale); // restore previous locale + $this->fail('Zend_Locale_Format::checkDateFormat emitted unexpected E_NOTICE'); } + setlocale(LC_ALL, $locale); // restore previous locale } /**