2008-03-20 04:00:49 +01:00
|
|
|
<?php
|
2008-06-15 15:33:53 +02:00
|
|
|
/**
|
|
|
|
* @package sapphire
|
|
|
|
* @subpackage tests
|
|
|
|
*/
|
2008-03-20 04:00:49 +01:00
|
|
|
class i18nTest extends SapphireTest {
|
2008-11-06 03:50:14 +01:00
|
|
|
|
|
|
|
/**
|
|
|
|
* @var string $tmpBasePath Used to write language files.
|
|
|
|
* We don't want to store them inside sapphire (or in any web-accessible place)
|
|
|
|
* in case something goes wrong with the file parsing.
|
|
|
|
*/
|
|
|
|
protected $alternateBaseSavePath;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @var string $alternateBasePath Fake webroot with a single module
|
|
|
|
* /i18ntestmodule which contains some files with _t() calls.
|
|
|
|
*/
|
|
|
|
protected $alternateBasePath;
|
2010-01-13 00:16:14 +01:00
|
|
|
|
|
|
|
protected $extraDataObjects = array(
|
|
|
|
'i18nTest_DataObject'
|
|
|
|
);
|
|
|
|
|
2008-11-06 03:50:14 +01:00
|
|
|
|
|
|
|
function setUp() {
|
|
|
|
parent::setUp();
|
|
|
|
|
|
|
|
$this->alternateBasePath = Director::baseFolder() . "/sapphire/tests/i18n/_fakewebroot";
|
|
|
|
$this->alternateBaseSavePath = TEMP_FOLDER . '/i18nTextCollectorTest_webroot';
|
|
|
|
FileSystem::makeFolder($this->alternateBaseSavePath);
|
|
|
|
|
|
|
|
// SSViewer and ManifestBuilder don't support different webroots, hence we set the paths manually
|
|
|
|
global $_CLASS_MANIFEST;
|
|
|
|
$_CLASS_MANIFEST['i18nTestModule'] = $this->alternateBasePath . '/i18ntestmodule/code/i18nTestModule.php';
|
|
|
|
$_CLASS_MANIFEST['i18nTestModule_Addition'] = $this->alternateBasePath . '/i18ntestmodule/code/i18nTestModule.php';
|
|
|
|
$_CLASS_MANIFEST['i18nTestModuleDecorator'] = $this->alternateBasePath . '/i18nothermodule/code/i18nTestModuleDecorator.php';
|
|
|
|
|
|
|
|
global $_ALL_CLASSES;
|
|
|
|
$_ALL_CLASSES['parents']['i18nTestModule'] = array('DataObject'=>'DataObject','Object'=>'Object');
|
|
|
|
$_ALL_CLASSES['parents']['i18nTestModule_Addition'] = array('Object'=>'Object');
|
|
|
|
$_ALL_CLASSES['parents']['i18nTestModuleDecorator'] = array('DataObjectDecorator'=>'DataObjectDecorator','Object'=>'Object');
|
|
|
|
|
|
|
|
global $_TEMPLATE_MANIFEST;
|
|
|
|
$_TEMPLATE_MANIFEST['i18nTestModule.ss'] = array(
|
|
|
|
'main' => $this->alternateBasePath . '/i18ntestmodule/templates/i18nTestModule.ss',
|
|
|
|
'Layout' => $this->alternateBasePath . '/i18ntestmodule/templates/Layout/i18nTestModule.ss',
|
|
|
|
);
|
|
|
|
$_TEMPLATE_MANIFEST['i18nTestModuleInclude.ss'] = array(
|
|
|
|
'Includes' => $this->alternateBasePath . '/i18ntestmodule/templates/Includes/i18nTestModuleInclude.ss',
|
|
|
|
);
|
2010-06-30 07:02:29 +02:00
|
|
|
|
|
|
|
$this->originalLocale = i18n::get_locale();
|
2008-11-06 03:50:14 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
function tearDown() {
|
|
|
|
//FileSystem::removeFolder($this->tmpBasePath);
|
|
|
|
|
|
|
|
global $_CLASS_MANIFEST;
|
|
|
|
unset($_CLASS_MANIFEST['i18nTestModule']);
|
|
|
|
unset($_CLASS_MANIFEST['i18nTestModule_Addition']);
|
|
|
|
|
|
|
|
global $_TEMPLATE_MANIFEST;
|
|
|
|
unset($_TEMPLATE_MANIFEST['i18nTestModule.ss']);
|
|
|
|
unset($_TEMPLATE_MANIFEST['i18nTestModuleInclude.ss']);
|
2008-11-12 04:11:57 +01:00
|
|
|
|
2010-06-30 07:02:29 +02:00
|
|
|
i18n::set_locale($this->originalLocale);
|
2008-12-04 23:38:32 +01:00
|
|
|
|
|
|
|
parent::tearDown();
|
2008-11-06 03:50:14 +01:00
|
|
|
}
|
|
|
|
|
2010-06-30 07:02:29 +02:00
|
|
|
function testDateFormatFromLocale() {
|
|
|
|
i18n::set_locale('en_US');
|
2010-10-10 23:01:32 +02:00
|
|
|
$this->assertEquals('MM/dd/yyyy', i18n::get_date_format());
|
2010-06-30 07:02:29 +02:00
|
|
|
i18n::set_locale('en_NZ');
|
|
|
|
$this->assertEquals('d/MM/yyyy', i18n::get_date_format());
|
|
|
|
i18n::set_locale('en_US');
|
|
|
|
}
|
|
|
|
|
|
|
|
function testTimeFormatFromLocale() {
|
|
|
|
i18n::set_locale('en_US');
|
2010-10-10 23:01:32 +02:00
|
|
|
$this->assertEquals('hh:mm a', i18n::get_time_format());
|
2010-06-30 07:02:29 +02:00
|
|
|
i18n::set_locale('de_DE');
|
|
|
|
$this->assertEquals('HH:mm:ss', i18n::get_time_format());
|
|
|
|
i18n::set_locale('en_US');
|
|
|
|
}
|
|
|
|
|
|
|
|
function testDateFormatCustom() {
|
|
|
|
i18n::set_locale('en_US');
|
2010-10-10 23:01:32 +02:00
|
|
|
$this->assertEquals('MM/dd/yyyy', i18n::get_date_format());
|
2010-06-30 07:02:29 +02:00
|
|
|
i18n::set_date_format('d/MM/yyyy');
|
|
|
|
$this->assertEquals('d/MM/yyyy', i18n::get_date_format());
|
|
|
|
}
|
|
|
|
|
|
|
|
function testTimeFormatCustom() {
|
|
|
|
i18n::set_locale('en_US');
|
2010-10-10 23:01:32 +02:00
|
|
|
$this->assertEquals('hh:mm a', i18n::get_time_format());
|
2010-06-30 07:02:29 +02:00
|
|
|
i18n::set_time_format('HH:mm:ss');
|
|
|
|
$this->assertEquals('HH:mm:ss', i18n::get_time_format());
|
|
|
|
}
|
|
|
|
|
2008-03-20 04:00:49 +01:00
|
|
|
function testGetExistingTranslations() {
|
|
|
|
$translations = i18n::get_existing_translations();
|
|
|
|
$this->assertTrue(isset($translations['en_US']), 'Checking for en_US translation');
|
|
|
|
$this->assertTrue(isset($translations['de_DE']), 'Checking for de_DE translation');
|
|
|
|
}
|
|
|
|
|
2008-10-29 22:07:17 +01:00
|
|
|
function testDataObjectFieldLabels() {
|
|
|
|
global $lang;
|
|
|
|
$oldLocale = i18n::get_locale();
|
|
|
|
i18n::set_locale('de_DE');
|
2008-11-01 14:26:08 +01:00
|
|
|
$obj = new i18nTest_DataObject();
|
2008-10-29 22:07:17 +01:00
|
|
|
|
2008-11-02 21:01:49 +01:00
|
|
|
$lang['en_US']['i18nTest_DataObject']['MyProperty'] = 'MyProperty';
|
|
|
|
$lang['de_DE']['i18nTest_DataObject']['MyProperty'] = 'Mein Attribut';
|
2010-01-29 03:20:31 +01:00
|
|
|
|
2008-10-29 22:07:17 +01:00
|
|
|
$this->assertEquals(
|
|
|
|
$obj->fieldLabel('MyProperty'),
|
|
|
|
'Mein Attribut'
|
|
|
|
);
|
|
|
|
|
2008-11-02 21:01:49 +01:00
|
|
|
$lang['en_US']['i18nTest_DataObject']['MyUntranslatedProperty'] = 'MyUntranslatedProperty';
|
2008-10-29 22:07:17 +01:00
|
|
|
$this->assertEquals(
|
|
|
|
$obj->fieldLabel('MyUntranslatedProperty'),
|
|
|
|
'My Untranslated Property'
|
|
|
|
);
|
|
|
|
|
|
|
|
i18n::set_locale($oldLocale);
|
|
|
|
}
|
|
|
|
|
2008-11-01 14:26:08 +01:00
|
|
|
function testProvideI18nEntities() {
|
|
|
|
global $lang;
|
|
|
|
$oldLocale = i18n::get_locale();
|
|
|
|
$lang['en_US']['i18nTest_Object']['my_translatable_property'] = 'Untranslated';
|
|
|
|
$lang['de_DE']['i18nTest_Object']['my_translatable_property'] = 'Übersetzt';
|
|
|
|
|
|
|
|
i18n::set_locale('en_US');
|
|
|
|
$this->assertEquals(
|
|
|
|
i18nTest_Object::$my_translatable_property,
|
|
|
|
'Untranslated'
|
|
|
|
);
|
|
|
|
$this->assertEquals(
|
|
|
|
i18nTest_Object::my_translatable_property(),
|
|
|
|
'Untranslated'
|
|
|
|
);
|
|
|
|
|
|
|
|
i18n::set_locale('en_US');
|
|
|
|
$this->assertEquals(
|
|
|
|
i18nTest_Object::my_translatable_property(),
|
|
|
|
'Untranslated',
|
|
|
|
'Getter returns original static value when called in default locale'
|
|
|
|
);
|
|
|
|
|
|
|
|
i18n::set_locale('de_DE');
|
|
|
|
$this->assertEquals(
|
|
|
|
i18nTest_Object::my_translatable_property(),
|
|
|
|
'Übersetzt',
|
|
|
|
'Getter returns translated value when called in another locale'
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
2008-11-06 03:50:14 +01:00
|
|
|
function testTemplateTranslation() {
|
|
|
|
global $lang;
|
|
|
|
$oldLocale = i18n::get_locale();
|
|
|
|
|
|
|
|
i18n::set_locale('en_US');
|
|
|
|
$lang['en_US']['i18nTestModule']['MAINTEMPLATE'] = 'Main Template';
|
|
|
|
$lang['en_US']['i18nTestModule.ss']['SPRINTFNONAMESPACE'] = 'My replacement no namespace: %s';
|
|
|
|
$lang['en_US']['i18nTestModule']['LAYOUTTEMPLATE'] = 'Layout Template';
|
|
|
|
$lang['en_US']['i18nTestModule.ss']['LAYOUTTEMPLATENONAMESPACE'] = 'Layout Template no namespace';
|
|
|
|
$lang['en_US']['i18nTestModule']['SPRINTFNAMESPACE'] = 'My replacement: %s';
|
|
|
|
$lang['en_US']['i18nTestModule']['WITHNAMESPACE'] = 'Include Entity with Namespace';
|
|
|
|
$lang['en_US']['i18nTestModule.ss']['NONAMESPACE'] = 'Include Entity without Namespace';
|
|
|
|
$lang['en_US']['i18nTestModuleInclude.ss']['SPRINTFINCLUDENAMESPACE'] = 'My include replacement: %s';
|
|
|
|
$lang['en_US']['i18nTestModule.ss']['SPRINTFINCLUDENONAMESPACE'] = 'My include replacement no namespace: %s';
|
|
|
|
$viewer = new SSViewer('i18nTestModule');
|
|
|
|
$parsedHtml = $viewer->process(new ArrayData(array('TestProperty' => 'TestPropertyValue')));
|
|
|
|
$this->assertContains(
|
2011-02-25 03:15:27 +01:00
|
|
|
sprintf("Layout Template%s", PHP_EOL),
|
2008-11-06 03:50:14 +01:00
|
|
|
$parsedHtml
|
|
|
|
);
|
|
|
|
$this->assertContains(
|
2011-02-25 03:15:27 +01:00
|
|
|
sprintf("Layout Template no namespace%s", PHP_EOL),
|
2008-11-06 03:50:14 +01:00
|
|
|
$parsedHtml
|
|
|
|
);
|
|
|
|
|
|
|
|
i18n::set_locale('de_DE');
|
|
|
|
$lang['de_DE']['i18nTestModule']['MAINTEMPLATE'] = 'TRANS Main Template';
|
|
|
|
$lang['de_DE']['i18nTestModule.ss']['SPRINTFNONAMESPACE'] = 'TRANS My replacement no namespace: %s';
|
|
|
|
$lang['de_DE']['i18nTestModule']['LAYOUTTEMPLATE'] = 'TRANS Layout Template';
|
|
|
|
$lang['de_DE']['i18nTestModule.ss']['LAYOUTTEMPLATENONAMESPACE'] = 'TRANS Layout Template no namespace';
|
|
|
|
$lang['de_DE']['i18nTestModule']['SPRINTFNAMESPACE'] = 'TRANS My replacement: %s';
|
|
|
|
$lang['de_DE']['i18nTestModule']['WITHNAMESPACE'] = 'TRANS Include Entity with Namespace';
|
2010-01-29 03:20:31 +01:00
|
|
|
$lang['de_DE']['i18nTestModuleInclude.ss']['NONAMESPACE'] = 'TRANS Include Entity without Namespace';
|
2008-11-06 03:50:14 +01:00
|
|
|
$lang['de_DE']['i18nTestModuleInclude.ss']['SPRINTFINCLUDENAMESPACE'] = 'TRANS My include replacement: %s';
|
|
|
|
$lang['de_DE']['i18nTestModule.ss']['SPRINTFINCLUDENONAMESPACE'] = 'TRANS My include replacement no namespace: %s';
|
|
|
|
$viewer = new SSViewer('i18nTestModule');
|
|
|
|
$parsedHtml = $viewer->process(new ArrayData(array('TestProperty' => 'TestPropertyValue')));
|
|
|
|
$this->assertContains(
|
2011-02-25 03:15:27 +01:00
|
|
|
sprintf("TRANS Main Template%s", PHP_EOL),
|
2008-11-06 03:50:14 +01:00
|
|
|
$parsedHtml
|
|
|
|
);
|
|
|
|
$this->assertContains(
|
2011-02-25 03:15:27 +01:00
|
|
|
sprintf("TRANS Layout Template%s", PHP_EOL),
|
2008-11-06 03:50:14 +01:00
|
|
|
$parsedHtml
|
|
|
|
);
|
|
|
|
$this->assertContains(
|
|
|
|
"TRANS Layout Template no namespace",
|
|
|
|
$parsedHtml
|
|
|
|
);
|
|
|
|
$this->assertContains(
|
|
|
|
"TRANS My replacement: TestPropertyValue",
|
|
|
|
$parsedHtml
|
|
|
|
);
|
|
|
|
$this->assertContains(
|
|
|
|
"TRANS Include Entity with Namespace",
|
|
|
|
$parsedHtml
|
|
|
|
);
|
|
|
|
$this->assertContains(
|
|
|
|
"TRANS Include Entity without Namespace",
|
|
|
|
$parsedHtml
|
|
|
|
);
|
|
|
|
$this->assertContains(
|
|
|
|
"TRANS My include replacement: TestPropertyValue",
|
|
|
|
$parsedHtml
|
|
|
|
);
|
|
|
|
$this->assertContains(
|
|
|
|
"TRANS My include replacement no namespace: TestPropertyValue",
|
|
|
|
$parsedHtml
|
|
|
|
);
|
|
|
|
|
|
|
|
i18n::set_locale($oldLocale);
|
|
|
|
}
|
2009-04-30 01:15:38 +02:00
|
|
|
|
|
|
|
function testGetLocaleFromLang() {
|
|
|
|
$this->assertEquals('en_US', i18n::get_locale_from_lang('en'));
|
|
|
|
$this->assertEquals('de_DE', i18n::get_locale_from_lang('de_DE'));
|
|
|
|
$this->assertEquals('xy_XY', i18n::get_locale_from_lang('xy'));
|
|
|
|
}
|
2010-05-14 00:44:37 +02:00
|
|
|
|
|
|
|
function testRegisteredPlugin() {
|
|
|
|
global $lang;
|
|
|
|
|
2010-05-14 01:25:17 +02:00
|
|
|
// save lang state, if we don't do this we may break other tests
|
|
|
|
$oldLang = $lang;
|
|
|
|
|
2010-05-14 00:44:37 +02:00
|
|
|
$lang = array(); // clear translations
|
|
|
|
i18n::register_plugin("testPlugin", array("i18nTest", "translationTestPlugin"));
|
|
|
|
|
|
|
|
// We have to simulate what include_by_locale() does, including loading translation provider data.
|
|
|
|
$lang['en_US']["i18nTestProvider"]["foo"] = "bar_en";
|
|
|
|
$lang['de_DE']["i18nTestProvider"]["foo"] = "bar_de";
|
|
|
|
i18n::plugins_load('en_US');
|
|
|
|
|
|
|
|
i18n::set_locale('en_US');
|
|
|
|
$this->assertEquals(_t("i18nTestProvider.foo"), "baz_en");
|
|
|
|
i18n::set_locale('de_DE');
|
|
|
|
$this->assertEquals(_t("i18nTestProvider.foo"), "bar_de");
|
|
|
|
i18n::unregister_plugin("testTranslator");
|
2010-05-14 01:25:17 +02:00
|
|
|
|
|
|
|
$lang = $oldLang;
|
2010-05-14 00:44:37 +02:00
|
|
|
}
|
2010-12-03 01:47:57 +01:00
|
|
|
|
|
|
|
function testValidateLocale() {
|
|
|
|
$this->assertTrue(i18n::validate_locale('en_US'), 'Known locale in underscore format is valid');
|
|
|
|
$this->assertTrue(i18n::validate_locale('en-US'), 'Known locale in dash format is valid');
|
|
|
|
$this->assertFalse(i18n::validate_locale('en'), 'Short lang format is not valid');
|
|
|
|
$this->assertFalse(i18n::validate_locale('xx_XX'), 'Unknown locale in correct format is not valid');
|
|
|
|
$this->assertFalse(i18n::validate_locale(''), 'Empty string is not valid');
|
|
|
|
}
|
2010-05-14 00:44:37 +02:00
|
|
|
|
|
|
|
static function translationTestPlugin($locale) {
|
|
|
|
$result = array();
|
|
|
|
$result["en_US"]["i18nTestProvider"]["foo"] = "baz_en";
|
|
|
|
return $result;
|
|
|
|
}
|
2008-10-29 22:07:17 +01:00
|
|
|
}
|
|
|
|
|
2008-11-01 14:26:08 +01:00
|
|
|
class i18nTest_DataObject extends DataObject implements TestOnly {
|
2008-10-29 22:07:17 +01:00
|
|
|
|
|
|
|
static $db = array(
|
|
|
|
'MyProperty' => 'Varchar',
|
|
|
|
'MyUntranslatedProperty' => 'Text'
|
|
|
|
);
|
|
|
|
|
|
|
|
static $has_one = array(
|
|
|
|
'HasOneRelation' => 'Member'
|
|
|
|
);
|
|
|
|
|
|
|
|
static $has_many = array(
|
|
|
|
'HasManyRelation' => 'Member'
|
|
|
|
);
|
|
|
|
|
|
|
|
static $many_many = array(
|
|
|
|
'ManyManyRelation' => 'Member'
|
|
|
|
);
|
|
|
|
|
2009-04-29 02:07:39 +02:00
|
|
|
/**
|
|
|
|
*
|
|
|
|
* @param boolean $includerelations a boolean value to indicate if the labels returned include relation fields
|
|
|
|
*
|
|
|
|
*/
|
|
|
|
function fieldLabels($includerelations = true) {
|
|
|
|
$labels = parent::fieldLabels($includerelations);
|
2008-11-02 21:01:49 +01:00
|
|
|
$labels['MyProperty'] = _t('i18nTest_DataObject.MyProperty', 'My Property');
|
|
|
|
|
|
|
|
return $labels;
|
|
|
|
}
|
|
|
|
|
2008-05-16 06:14:50 +02:00
|
|
|
}
|
2008-11-01 14:26:08 +01:00
|
|
|
|
|
|
|
class i18nTest_Object extends Object implements TestOnly, i18nEntityProvider {
|
|
|
|
static $my_translatable_property = "Untranslated";
|
|
|
|
|
|
|
|
static function my_translatable_property() {
|
|
|
|
return _t("i18nTest_Object.my_translatable_property", self::$my_translatable_property);
|
|
|
|
}
|
|
|
|
|
|
|
|
function provideI18nEntities() {
|
|
|
|
return array(
|
|
|
|
"i18nTest_Object.my_translatable_property" => array(
|
|
|
|
self::$my_translatable_property
|
|
|
|
)
|
|
|
|
);
|
|
|
|
}
|
|
|
|
}
|
2008-10-29 22:07:17 +01:00
|
|
|
?>
|