From c3b894cb1fb1b7758629e7ad85841c4c4fca57c4 Mon Sep 17 00:00:00 2001 From: Steve Boyd Date: Fri, 24 Jan 2025 18:01:14 +1300 Subject: [PATCH] MNT Handle unit tests that cause LogicException to be thrown --- composer.json | 1 + src/Dev/SapphireTest.php | 24 +++++++++++-- tests/php/Dev/SapphireTestTest.php | 57 ++++++++++++++++++++++++++++++ 3 files changed, 79 insertions(+), 3 deletions(-) diff --git a/composer.json b/composer.json index 0b000071b02..97c5664e612 100644 --- a/composer.json +++ b/composer.json @@ -71,6 +71,7 @@ "phpstan/extension-installer": "^1.3" }, "conflict": { + "silverstripe/behat-extension": "<5.5", "egulias/email-validator": "^2", "oscarotero/html-parser": "<0.1.7", "symfony/process": "<5.3.7" diff --git a/src/Dev/SapphireTest.php b/src/Dev/SapphireTest.php index ab70eab6944..788fc4a5fd3 100644 --- a/src/Dev/SapphireTest.php +++ b/src/Dev/SapphireTest.php @@ -64,6 +64,13 @@ abstract class SapphireTest extends TestCase implements TestOnly */ protected static $fixture_file = null; + /** + * Whether to set the i18n locale to en_US for supported modules before running the test. + * This should only be set to false if calling setI18nLocale() causes the test to + * throw an exception as part of calling setI18nLocale() + */ + protected bool $doSetSupportedModuleLocaleToUS = true; + /** * @var Boolean If set to TRUE, this will force a test database to be generated * in {@link setUp()}. Note that this flag is overruled by the presence of a @@ -1239,6 +1246,10 @@ protected function mockSleep(int $seconds): DBDatetime */ private function setI18nLocale(): void { + if (!$this->doSetSupportedModuleLocaleToUS) { + $this->setLocaleToDefault(); + return; + } $path = $this->getCurrentRelativePath(); $packagistName = ''; if (preg_match('#(^|/)vendor/([^/]+/[^/]+)/.+#', $path, $matches)) { @@ -1261,9 +1272,16 @@ private function setI18nLocale(): void i18n::config()->set('default_locale', 'en_US'); i18n::set_locale('en_US'); } else { - // Set the locale to the default_locale, which may have been set at project level to a - // non-en_US locale and the project unit tests expect that locale to be set - i18n::set_locale(i18n::config()->get('default_locale')); + $this->setLocaleToDefault(); } } + + /** + * Set the locale to the default_locale, which may have been set at project level to a + * non-en_US locale and the project unit tests expect that locale to be set + */ + private function setLocaleToDefault(): void + { + i18n::set_locale(i18n::config()->get('default_locale')); + } } diff --git a/tests/php/Dev/SapphireTestTest.php b/tests/php/Dev/SapphireTestTest.php index 3b571c3c1ae..0007227a89e 100644 --- a/tests/php/Dev/SapphireTestTest.php +++ b/tests/php/Dev/SapphireTestTest.php @@ -7,6 +7,8 @@ use SilverStripe\ORM\ArrayList; use SilverStripe\Security\Member; use SilverStripe\Security\Permission; +use SilverStripe\i18n\i18n; +use ReflectionMethod; class SapphireTestTest extends SapphireTest { @@ -230,4 +232,59 @@ public function testAssertListEqualsFailsOnNonEqualLists($matches, $itemsForList $this->assertListEquals($matches, $list); } + + public static function provideSetI18nLocale(): array + { + return [ + 'supported-true' => [ + 'doSet' => true, + 'supported' => true, + 'expected' => 'en_US', + ], + 'supported-false' => [ + 'doSet' => false, + 'supported' => true, + 'expected' => 'ab_CD', + ], + 'unsupported-true' => [ + 'doSet' => true, + 'supported' => false, + 'expected' => 'ab_CD', + ], + 'unsupported-false' => [ + 'doSet' => false, + 'supported' => false, + 'expected' => 'ab_CD', + ], + ]; + } + + /** + * @dataProvider provideSetI18nLocale + */ + public function testSetI18nLocale(bool $doSet, bool $supported, string $expected): void + { + i18n::set_locale('ab_CD'); + i18n::config()->set('default_locale', 'ab_CD'); + $method = new ReflectionMethod(SapphireTest::class, 'setI18nLocale'); + $method->setAccessible(true); + $obj = new class($doSet, $supported) extends SapphireTest + { + private string $supported; + public function __construct(bool $doSet, bool $supported) + { + $this->doSetSupportedModuleLocaleToUS = $doSet; + $this->supported = $supported; + } + protected function getCurrentRelativePath() + { + return $this->supported + ? '/vendor/silverstripe/framework/tests/php/FooBarTest.php' + : '/vendor/something/different/tests/php/FooBarTest.php'; + } + }; + $method->invoke($obj); + $this->assertEquals($expected, i18n::get_locale()); + $this->assertEquals($expected, i18n::config()->get('default_locale')); + } }