From 8491b62a8330e2e71165900ed87888addb1669fb Mon Sep 17 00:00:00 2001 From: Joshua Ramon Enslin Date: Fri, 4 Apr 2025 20:03:59 +0200 Subject: [PATCH] Validate against time errors in autogenerating translations for times Close #30 --- src/NodaTimeAutotranslater.php | 78 ++++++++++++++++++++++++++-- tests/NodaTimeAutotranslaterTest.php | 27 ++++++++-- 2 files changed, 99 insertions(+), 6 deletions(-) diff --git a/src/NodaTimeAutotranslater.php b/src/NodaTimeAutotranslater.php index 9ff6e74..1466469 100644 --- a/src/NodaTimeAutotranslater.php +++ b/src/NodaTimeAutotranslater.php @@ -13,7 +13,7 @@ final class NodaTimeAutotranslater { // TODO: Move these to NodaTimeAutotranslaterLocales - const LANGS_SYLLABLE_CLEANING = [ + public const LANGS_SYLLABLE_CLEANING = [ "hu" => [ "10-as évek" => "10-es évek", "40-as évek" => "40-es évek", @@ -463,13 +463,13 @@ final class NodaTimeAutotranslater { } /** - * Gets translations for a given entry type. + * Prepares translations for each available language. * * @param array $timeInfo Time information. * * @return array */ - public static function getTranslations(array $timeInfo):array { + public static function prepareTranslations(array $timeInfo):array { if (!empty($timeInfo['zeit_name']) and strlen((string)$timeInfo['zeit_name']) > 10 and !empty($timespanDates = NodaTimeSplitter::attempt_splitting_from_till((string)$timeInfo['zeit_name']))) { @@ -604,6 +604,78 @@ final class NodaTimeAutotranslater { } + /** + * Validates correctness of years in translation strings. + * + * @param string|integer $start Start year. + * @param string|integer $end End year. + * @param array $translations Translations. + * + * @return boolean + */ + public static function validateTranslations(string|int $start, string|int $end, array $translations):bool { + + $start = ltrim((string)$start, ' 0-'); + $end = ltrim((string)$end, ' 0-'); + + // Edge cases: Centuries and decades have special translations + // and can thus not be validated properly + // Century BCE + if (substr($start, -1) === "0" && substr($end, -1) === '1' && $start > $end) { + return true; + } + // Century CE + if (substr($start, -1) === "1" && substr($end, -1) === '0' && $start < $end) { + return true; + } + // Decade + if (substr($start, -1) === "0" && substr($end, -1) === '9' && $start < $end) { + return true; + } + + // 1920 + ? can be both Since 1920 and After 1919, so validation + // is impossible there, too + if ($start === '?' || $end === '?') return true; + + // Unset unvalidatable languages + unset($translations['ar'], $translations['fa']); + + if ($start !== '?') { + foreach ($translations as $t) { + if (!str_contains($t, $start)) { + return false; + } + } + } + if ($end !== '?' && $start !== $end) { + foreach ($translations as $t) { + if (!str_contains($t, $end)) { + return false; + } + } + } + + return true; + + } + + /** + * Gets translations for a given entry type. + * + * @param array $timeInfo Time information. + * + * @return array + */ + public static function getTranslations(array $timeInfo):array { + + $output = self::prepareTranslations($timeInfo); + + if (self::validateTranslations($timeInfo['zeit_beginn'], $timeInfo['zeit_ende'], $output) === false) return []; + + return $output; + + } + /** * Runs autotranslater. * diff --git a/tests/NodaTimeAutotranslaterTest.php b/tests/NodaTimeAutotranslaterTest.php index d8bfda9..ac0af7f 100644 --- a/tests/NodaTimeAutotranslaterTest.php +++ b/tests/NodaTimeAutotranslaterTest.php @@ -6,12 +6,14 @@ */ declare(strict_types = 1); use PHPUnit\Framework\TestCase; +use PHPUnit\Framework\Attributes\CoversClass; +use PHPUnit\Framework\Attributes\Medium; /** * This script contains tests for the automatic translation class for time names. - * - * @covers \NodaTimeAutotranslater */ +#[Medium] +#[CoversClass(\NodaIDGetter::class)] final class NodaTimeAutotranslaterTest extends TestCase { /** * Test to check whether the HTML page is correctly generated. @@ -32,7 +34,7 @@ final class NodaTimeAutotranslaterTest extends TestCase { "zeit_zaehlzeit_tag" => "01", ]; $output = NodaTimeAutotranslater::getTranslations($timeInfo); - self::assertEquals($output["de"], "01.05.1920"); + self::assertEquals("01.05.1920", $output["de"]); } @@ -671,4 +673,23 @@ final class NodaTimeAutotranslaterTest extends TestCase { self::assertEquals($output["de"], "Vor 01.12.1919"); } + + /** + * Test to check whether validating works. + * + * @author Joshua Ramon Enslin + * @group ValidOutput + * @small + * + * @return void + */ + public function testValidation():void { + + $output = [ + 'de' => '1.12.1920', + ]; + + self::assertFalse(NodaTimeAutotranslater::validateTranslations("1919", "1919", $output)); + + } }