Files
FreshRSS/tests/cli/i18n/PluralFormsCompilerTest.php
Christian Weiske 1acc646222 Show time since when a feed has problems + new timeago() method and i18n plurals (#8670)
Closes https://github.com/FreshRSS/FreshRSS/issues/8508

Changes proposed in this pull request:

- Use an integer for `Feed::error` everywhere (follow up to #8646)
- Extract `Entry::machineReadableDate()` into function for use in HTML templates
- Add `timeago()` function that converts a unix timestamp into a "4 weeks ago" string
- Show the last successful feed update, and the last erroneous update

How to test the feature manually:

1. Update a feed
2. Modify the feed URL in the database and set it to a non-existing URL
3. Update the feed again
4. Open the "Manage feed" and see the expanded error message:

>  Blast! This feed has encountered a problem. If this situation persists, please verify that it is still reachable.
> Last successful update 3 hours ago, last erroneous update 1 hour ago. 

You can hover the relative dates to see the timestamp.

* Make Feed::error an int everywhere

Related: https://github.com/FreshRSS/FreshRSS/pull/8646

* Extract timestamptomachinedate()

.. for later usage in the feed error time display.

* Show time since when a feed has problems

We add our own "timeago" function that converts a unix timestamp
into a "4 weeks ago" string.

Resolves: https://github.com/FreshRSS/FreshRSS/issues/8508

* Add new translation keys

* i18n fr, en-US

* Minor XHTML preference

* Slightly shorter rewrite, also hopefully easier to read

* Rewrite to allow (simple) plural
I also moved some functions around for hopefully a more generic and better structure.
I made some changes for the sake of speed (e.g. second-based logic instead of datetime intervals).
Note: I used automatic translation as I was worried it would be too complicated to explain to translators... I proofread the few languages I have some familiarity with.

* Add reference to CLDR

* Slightly more compact syntax

* Always show last update, fix case of unknown error date

* Remove forgotten span

* No need for multi-lines anymore

* Fix error date thresshold

* plurals forms

* Extract gettext formula conversion script to cli

* Simplify a bit

* Escort excess parentheses to the door

* Simplify

* Avoid being too clever in localization

* Fix German

* Fix plural TODO parsing

* Ignore en-US translation

* make fix-all

* git update-index --chmod=+x cli/compile.plurals.php

* Heredoc indent PHP 7.3+

* compileAll: Continue on error

* PHP strict comparisons

* Light logical simplification

* Cache plural_message_families

* Avoid case of empty value

* A bit of documentation

---------

Co-authored-by: Alexandre Alapetite <alexandre@alapetite.fr>
Co-authored-by: Frans de Jonge <frans@clevercast.com>
Co-authored-by: Frans de Jonge <fransdejonge@gmail.com>
2026-04-07 22:56:02 +02:00

82 lines
2.8 KiB
PHP

<?php
declare(strict_types=1);
require_once dirname(__DIR__, 3) . '/cli/i18n/PluralFormsCompiler.php';
final class PluralFormsCompilerTest extends \PHPUnit\Framework\TestCase {
public function testCompileFormulaToLambda(): void {
$compiler = new PluralFormsCompiler();
$compiled = $compiler->compileFormula('nplurals=3; plural=(n==1) ? 0 : (n>=2 && n<=4) ? 1 : 2;');
self::assertSame('nplurals=3; plural=(n==1) ? 0 : (n>=2 && n<=4) ? 1 : 2;', $compiled['formula']);
self::assertSame(3, $compiled['nplurals']);
self::assertSame(
'static fn (int $n): int => ($n === 1 ? 0 : ($n >= 2 && $n <= 4 ? 1 : 2))',
$compiled['lambda']
);
$lambda = eval('return ' . $compiled['lambda'] . ';');
self::assertInstanceOf(Closure::class, $lambda);
self::assertSame(0, $lambda(1));
self::assertSame(1, $lambda(3));
self::assertSame(2, $lambda(5));
}
public function testCompileFormulaNormalisesPluralFormsComment(): void {
$compiler = new PluralFormsCompiler();
$compiled = $compiler->compileFormula('// Plural-Forms: nplurals=2; plural=(n != 1);');
self::assertSame('nplurals=2; plural=(n != 1);', $compiled['formula']);
self::assertSame('static fn (int $n): int => (($n !== 1) ? 1 : 0)', $compiled['lambda']);
$lambda = eval('return ' . $compiled['lambda'] . ';');
self::assertInstanceOf(Closure::class, $lambda);
self::assertSame(0, $lambda(1));
self::assertSame(1, $lambda(2));
}
public function testCompileFormulaHandlesModuloAndLogicalOperators(): void {
$compiler = new PluralFormsCompiler();
$compiled = $compiler->compileFormula(
'nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);'
);
$lambda = eval('return ' . $compiled['lambda'] . ';');
self::assertInstanceOf(Closure::class, $lambda);
self::assertSame(0, $lambda(1));
self::assertSame(1, $lambda(2));
self::assertSame(2, $lambda(5));
self::assertSame(2, $lambda(11));
}
public function testCompileFileMigratesLegacyPluralFile(): void {
$compiler = new PluralFormsCompiler();
$tempFile = tempnam(sys_get_temp_dir(), 'plural-forms-');
self::assertNotFalse($tempFile);
try {
file_put_contents($tempFile, <<<'PHP'
<?php
return array(
'plural-forms' => 'nplurals=2; plural=(n != 1);',
);
PHP);
self::assertTrue($compiler->compileFile($tempFile));
$fileContent = file_get_contents($tempFile);
self::assertIsString($fileContent);
self::assertStringContainsString('// Plural-Forms: nplurals=2; plural=(n != 1);', $fileContent);
$pluralData = include $tempFile;
self::assertIsArray($pluralData);
self::assertSame(2, $pluralData['nplurals']);
self::assertInstanceOf(Closure::class, $pluralData['plural']);
self::assertSame(0, $pluralData['plural'](1));
self::assertSame(1, $pluralData['plural'](2));
} finally {
@unlink($tempFile);
}
}
}