From c87c3b100c459094aa90ca1421e6fa6d6416a4e2 Mon Sep 17 00:00:00 2001 From: MDW Date: Wed, 27 Mar 2024 21:51:21 +0100 Subject: [PATCH] Qual: LangTest: Use dataprovider, beautify output --- test/phpunit/LangTest.php | 210 +++++++++++++++++++++++--------------- 1 file changed, 130 insertions(+), 80 deletions(-) diff --git a/test/phpunit/LangTest.php b/test/phpunit/LangTest.php index f7b43ddb6e3..2acecab4545 100644 --- a/test/phpunit/LangTest.php +++ b/test/phpunit/LangTest.php @@ -1,6 +1,7 @@ * Copyright (C) 2023 Alexandre Janniaux + * Copyright (C) 2024 MDW * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -64,7 +65,7 @@ if (! defined("NOLOGIN")) { } if (empty($user->id)) { - print "Load permissions for admin user nb 1\n"; + print "Load permissions for admin user nb 1".PHP_EOL; $user->fetch(1); $user->getrights(); } @@ -81,11 +82,33 @@ $conf->global->MAIN_DISABLE_ALL_MAILS = 1; class LangTest extends CommonClassTest { /** - * testLang + * Data provider for testLang * - * @return string + * @return array */ - public function testLang() + public function langDataProvider(): array + { + $langCodes = []; + $filesarray = scandir(DOL_DOCUMENT_ROOT.'/langs'); + foreach ($filesarray as $key => $code) { + if (! preg_match('/^[a-z]+_[A-Z]+$/', $code)) { + continue; + } + $langCodes[$code] = [$code]; + } + return $langCodes; + } + + + /** + * testLang + * @dataProvider langDataProvider + * + * @param $code Language code for which to verify translations + * + * @return void + */ + public function testLang($code): void { global $conf,$user,$langs,$db; $conf = $this->savconf; @@ -95,96 +118,123 @@ class LangTest extends CommonClassTest include_once DOL_DOCUMENT_ROOT.'/core/class/translate.class.php'; - $filesarray = scandir(DOL_DOCUMENT_ROOT.'/langs'); - foreach ($filesarray as $key => $code) { - if (! preg_match('/^[a-z]+_[A-Z]+$/', $code)) { + + $prefix = __METHOD__."($code) "; + $tmplangs = new Translate('', $conf); + $langcode = $code; + $tmplangs->setDefaultLang($langcode); + $tmplangs->load("main"); + + print PHP_EOL.$prefix."Check language file".PHP_EOL; + $result = $tmplangs->transnoentitiesnoconv("FONTFORPDF"); + print $prefix."FONTFORPDF=".$result.PHP_EOL; + $this->assertTrue(in_array($result, array('msungstdlight', 'stsongstdlight', 'helvetica', 'DejaVuSans', 'cid0jp', 'cid0kr', 'freemono', 'freeserif')), 'Error bad value '.$result.' for FONTFORPDF in main.lang file '.$code); + + $result = $tmplangs->transnoentitiesnoconv("DIRECTION"); + print $prefix."DIRECTION=".$result.PHP_EOL; + $this->assertTrue(in_array($result, array('rtl', 'ltr')), 'Error bad value for DIRECTION in main.lang file '.$code); + + $result = $tmplangs->transnoentitiesnoconv("SeparatorDecimal"); + print $prefix."SeparatorDecimal=".$result.PHP_EOL; + $this->assertTrue(in_array($result, array('.',',','/','。',' ','','None')), 'Error on decimal separator for lang code '.$code); // Note that ، that is coma for RTL languages is not supported + + $result = $tmplangs->transnoentitiesnoconv("SeparatorThousand"); + print $prefix."SeparatorThousand=".$result.PHP_EOL; + $this->assertTrue(in_array($result, array('.',',','/',' ','','\'','None','Space')), 'Error on thousand separator for lang code '.$code); // Note that ، that is coma for RTL languages is not supported + + // Test java string contains only d,M,y,/,-,. and not m,... + $result = $tmplangs->transnoentitiesnoconv("FormatDateShortJava"); + print $prefix."FormatDateShortJava=".$result.PHP_EOL; + $tmpvar = preg_match('/^[dMy\/\-\.]+$/', $result); + $this->assertEquals(1, $tmpvar, 'FormatDateShortJava KO for lang code '.$code.'. Does not match /[dMy\/\-\.]+/'); + + $result = $tmplangs->trans("FormatDateShortJavaInput"); + print $prefix."FormatDateShortJavaInput=".$result.PHP_EOL; + $tmpvar = preg_match('/^[dMy\/\-\.]+$/', $result); + $this->assertEquals(1, $tmpvar, 'FormatDateShortJavaInput KO for lang code '.$code.'. Does not match /^[dMy\/\-\.]+$/'); + + unset($tmplangs); + + print $prefix."Check some syntax rules in the language file".PHP_EOL; + $filesarray2 = scandir(DOL_DOCUMENT_ROOT.'/langs/'.$code); + foreach ($filesarray2 as $key => $file) { + if (! preg_match('/\.lang$/', $file)) { continue; } - print 'Check language file for lang code='.$code."\n"; - $tmplangs = new Translate('', $conf); - $langcode = $code; - $tmplangs->setDefaultLang($langcode); - $tmplangs->load("main"); + //print 'Check lang file '.$file.PHP_EOL; + $filecontent = file_get_contents(DOL_DOCUMENT_ROOT.'/langs/'.$code.'/'.$file); - $result = $tmplangs->transnoentitiesnoconv("FONTFORPDF"); - print __METHOD__." FONTFORPDF=".$result."\n"; - $this->assertTrue(in_array($result, array('msungstdlight', 'stsongstdlight', 'helvetica', 'DejaVuSans', 'cid0jp', 'cid0kr', 'freemono', 'freeserif')), 'Error bad value '.$result.' for FONTFORPDF in main.lang file '.$code); + $result = preg_match('/=--$/m', $filecontent); // A special % char we don't want. We want the common one. + //print $prefix."Result for checking we don't have bad percent char = ".$result.PHP_EOL; + $this->assertTrue($result == 0, 'Found a translation KEY=-- in file '.$code.'/'.$file.'. We probably want Key=- instead.'); - $result = $tmplangs->transnoentitiesnoconv("DIRECTION"); - print __METHOD__." DIRECTION=".$result."\n"; - $this->assertTrue(in_array($result, array('rtl', 'ltr')), 'Error bad value for DIRECTION in main.lang file '.$code); + $result = strpos($filecontent, '%'); // A special % char we don't want. We want the common one. + //print $prefix."Result for checking we don't have bad percent char = ".$result.PHP_EOL; + $this->assertTrue($result === false, 'Found a bad percent char % instead of % in file '.$code.'/'.$file); - $result = $tmplangs->transnoentitiesnoconv("SeparatorDecimal"); - print __METHOD__." SeparatorDecimal=".$result."\n"; - $this->assertTrue(in_array($result, array('.',',','/','。',' ','','None')), 'Error on decimal separator for lang code '.$code); // Note that ، that is coma for RTL languages is not supported + $result = preg_match('/%n/m', $filecontent); // A sequence of char we don't want + //print $prefix."Result for checking we don't have bad percent char = ".$result.PHP_EOL; + $this->assertTrue($result == 0, 'Found a sequence %n in the translation file '.$code.'/'.$file.'. We probably want %s'); - $result = $tmplangs->transnoentitiesnoconv("SeparatorThousand"); - print __METHOD__." SeparatorThousand=".$result."\n"; - $this->assertTrue(in_array($result, array('.',',','/',' ','','\'','None','Space')), 'Error on thousand separator for lang code '.$code); // Note that ، that is coma for RTL languages is not supported + $result = preg_match('/<<<<assertEquals(1, $tmpvar, 'FormatDateShortJava KO for lang code '.$code.'. Does not match /[dMy\/\-\.]+/'); - - $result = $tmplangs->trans("FormatDateShortJavaInput"); - print __METHOD__." FormatDateShortJavaInput=".$result."\n"; - $tmpvar = preg_match('/^[dMy\/\-\.]+$/', $result); - $this->assertEquals(1, $tmpvar, 'FormatDateShortJavaInput KO for lang code '.$code.'. Does not match /^[dMy\/\-\.]+$/'); - - unset($tmplangs); - - print "Check also some syntax rules into the language file\n"; - $filesarray2 = scandir(DOL_DOCUMENT_ROOT.'/langs/'.$code); - foreach ($filesarray2 as $key => $file) { - if (! preg_match('/\.lang$/', $file)) { - continue; - } - - //print 'Check lang file '.$file."\n"; - $filecontent = file_get_contents(DOL_DOCUMENT_ROOT.'/langs/'.$code.'/'.$file); - - $result = preg_match('/=--$/m', $filecontent); // A special % char we don't want. We want the common one. - //print __METHOD__." Result for checking we don't have bad percent char = ".$result."\n"; - $this->assertTrue($result == 0, 'Found a translation KEY=-- into file '.$code.'/'.$file.'. We probably want Key=- instead.'); - - $result = strpos($filecontent, '%'); // A special % char we don't want. We want the common one. - //print __METHOD__." Result for checking we don't have bad percent char = ".$result."\n"; - $this->assertTrue($result === false, 'Found a bad percent char % instead of % into file '.$code.'/'.$file); - - $result = preg_match('/%n/m', $filecontent); // A sequence of char we don't want - //print __METHOD__." Result for checking we don't have bad percent char = ".$result."\n"; - $this->assertTrue($result == 0, 'Found a sequence %n into the translation file '.$code.'/'.$file.'. We probably want %s'); - - $result = preg_match('/<<<<assertTrue($result == 0, 'Found a sequence <<<<< into the translation file '.$code.'/'.$file.'. Probably a bad merge of code were done.'); + $reg = array(); + $result = preg_match('/(.*)\'notranslate\'/im', $filecontent, $reg); // A sequence of char we don't want + //print $prefix."Result for checking we don't have bad percent char = ".$result.PHP_EOL; + $this->assertTrue($result == 0, 'Found a sequence tag \'notranslate\' in the translation file '.$code.'/'.$file.' in line '.empty($reg[1]) ? '' : $reg[1]); + if (!in_array($code, array('ar_SA'))) { $reg = array(); - $result = preg_match('/(.*)\'notranslate\'/im', $filecontent, $reg); // A sequence of char we don't want - //print __METHOD__." Result for checking we don't have bad percent char = ".$result."\n"; - $this->assertTrue($result == 0, 'Found a sequence tag \'notranslate\' into the translation file '.$code.'/'.$file.' in line '.empty($reg[1]) ? '' : $reg[1]); - - if (!in_array($code, array('ar_SA'))) { - $reg = array(); - $result = preg_match('/(.*)<([^a-z\/\s,=\(]1)/im', $filecontent, $reg); // A sequence of char we don't want - //print __METHOD__." Result for checking we don't have bad percent char = ".$result."\n"; - $this->assertTrue($result == 0, 'Found a sequence tag <'.(empty($reg[2]) ? '': $reg[2]).' into the translation file '.$code.'/'.$file.' in line '.empty($reg[1]) ? '' : $reg[1]); - } + $result = preg_match('/(.*)<([^a-z\/\s,=\(]1)/im', $filecontent, $reg); // A sequence of char we don't want + //print $prefix."Result for checking we don't have bad percent char = ".$result.PHP_EOL; + $this->assertTrue($result == 0, 'Found a sequence tag <'.(empty($reg[2]) ? '' : $reg[2]).' in the translation file '.$code.'/'.$file.' in line '.empty($reg[1]) ? '' : $reg[1]); } } - - return; } + + /** + * Data provider for testTrans + * + * @return array + */ + public function transDataProvider(): array + { + return [ + 'en_US-1' => [ + 'Result of lang->trans must have original translation string with its original HTML tag, but inserted values must be fully encoded.', // Description + "en_US", // Langcode + "main", // Dict + "Search criteria '<input autofocus onfocus='alert(1337)' <--!' into fields ", // Expected + "FilterOnInto", " [ + 'Result of lang->trans must have original translation string with its original HTML tag, but inserted values must be fully encoded.', // Description + "fr_FR", // Langcode + "main", // Dict + "Rechercher le critère '<input autofocus onfocus='alert(1337)' <--!' dans les champs ", // Expected + "FilterOnInto", "savconf; @@ -193,12 +243,12 @@ class LangTest extends CommonClassTest $db = $this->savdb; $tmplangs = new Translate('', $conf); - $langcode = 'en_US'; $tmplangs->setDefaultLang($langcode); - $tmplangs->load("main"); + $tmplangs->load($dict); - $result = $tmplangs->trans("FilterOnInto", "assertEquals($result, "Search criteria '<input autofocus onfocus='alert(1337)' <--!' into fields ", 'Result of lang->trans must have original translation string with its original HTML tag, but inserted values must be fully encoded.'); + $result = $tmplangs->trans($key, $param1, $param2); + $prefix = __METHOD__."({$this->dataName()}) "; + print $prefix."result trans $key = ".$result.PHP_EOL; + $this->assertEquals($expected, $result, $description); } }