big restructure

This commit is contained in:
2026-02-11 19:28:12 +01:00
parent cd59ccd99b
commit 3eb9cc0ac4
209 changed files with 5101 additions and 2459 deletions

View File

@@ -0,0 +1,102 @@
<?php
namespace MintyPHP\Tests\I18n;
use PHPUnit\Framework\TestCase;
use RecursiveDirectoryIterator;
use RecursiveIteratorIterator;
class TranslationKeysTest extends TestCase
{
public function testAllTranslationKeysExistInDefaultLocales(): void
{
$root = realpath(__DIR__ . '/../..');
$this->assertNotFalse($root, 'Project root not found.');
$paths = [
$root . '/pages',
$root . '/templates',
$root . '/lib',
$root . '/web/js',
];
$extensions = ['php', 'phtml', 'js'];
$usedKeys = [];
foreach ($paths as $path) {
if (!is_dir($path)) {
continue;
}
$iterator = new RecursiveIteratorIterator(new RecursiveDirectoryIterator($path));
foreach ($iterator as $file) {
if (!$file->isFile()) {
continue;
}
$ext = strtolower((string) $file->getExtension());
if (!in_array($ext, $extensions, true)) {
continue;
}
$content = file_get_contents($file->getPathname());
if ($content === false || $content === '') {
continue;
}
foreach ($this->extractTranslationKeys($content) as $key) {
$usedKeys[$key] = true;
}
}
}
$usedKeys = array_keys($usedKeys);
sort($usedKeys);
$locales = [
'default_de.json' => $root . '/i18n/default_de.json',
'default_en.json' => $root . '/i18n/default_en.json',
];
$translations = [];
foreach ($locales as $name => $path) {
$this->assertFileExists($path, 'Missing locale file: ' . $name);
$raw = file_get_contents($path);
$this->assertNotFalse($raw, 'Failed to read locale file: ' . $name);
$json = json_decode($raw, true);
$this->assertIsArray($json, 'Invalid JSON in locale file: ' . $name);
$translations[$name] = $json;
}
$missing = [];
foreach ($usedKeys as $key) {
foreach ($translations as $name => $map) {
if (!array_key_exists($key, $map)) {
$missing[$name][] = $key;
}
}
}
$messages = [];
foreach ($missing as $name => $keys) {
$messages[] = $name . ' missing: ' . implode(', ', $keys);
}
$this->assertSame([], $missing, implode(' | ', $messages));
}
private function extractTranslationKeys(string $content): array
{
$keys = [];
// Match t('...') with escaped quotes inside, and the same for t("...").
$patterns = [
"/\\bt\\s*\\(\\s*'((?:\\\\\\\\.|[^'\\\\\\\\])*)'\\s*\\)/",
'/\\bt\\s*\\(\\s*"((?:\\\\\\\\.|[^"\\\\\\\\])*)"\\s*\\)/',
];
foreach ($patterns as $pattern) {
if (!preg_match_all($pattern, $content, $matches)) {
continue;
}
foreach ($matches[1] as $match) {
$keys[] = stripcslashes($match);
}
}
return $keys;
}
}

View File

@@ -0,0 +1,83 @@
<?php
namespace MintyPHP\Tests\Repository;
use MintyPHP\Repository\Support\RepoQuery;
use PHPUnit\Framework\TestCase;
class RepoQueryTest extends TestCase
{
public function testSanitizeLimitOffsetDefaults(): void
{
[$limit, $offset] = RepoQuery::sanitizeLimitOffset([]);
$this->assertSame(10, $limit);
$this->assertSame(0, $offset);
}
public function testSanitizeLimitOffsetBounds(): void
{
[$limit, $offset] = RepoQuery::sanitizeLimitOffset(['limit' => 0, 'offset' => -5]);
$this->assertSame(10, $limit);
$this->assertSame(0, $offset);
[$limit, $offset] = RepoQuery::sanitizeLimitOffset(['limit' => 999, 'offset' => 5]);
$this->assertSame(100, $limit);
$this->assertSame(5, $offset);
}
public function testSanitizeOrder(): void
{
[$order, $dir] = RepoQuery::sanitizeOrder(['order' => 'name', 'dir' => 'ASC'], ['id', 'name']);
$this->assertSame('name', $order);
$this->assertSame('asc', $dir);
[$order, $dir] = RepoQuery::sanitizeOrder(['order' => 'bad', 'dir' => 'weird'], ['id', 'name']);
$this->assertSame('id', $order);
$this->assertSame('desc', $dir);
}
public function testAddLikeFilter(): void
{
$where = [];
$params = [];
RepoQuery::addLikeFilter($where, $params, ['a', 'b'], '');
$this->assertSame([], $where);
$this->assertSame([], $params);
RepoQuery::addLikeFilter($where, $params, ['a', 'b'], 'foo');
$this->assertSame(['(a like ? or b like ?)'], $where);
$this->assertSame(['%foo%', '%foo%'], $params);
}
public function testAddEnumFilter(): void
{
$where = [];
$params = [];
RepoQuery::addEnumFilter($where, $params, 'active', [
['aliases' => ['active'], 'sql' => 'status = ?', 'params' => ['1']],
]);
$this->assertSame(['status = ?'], $where);
$this->assertSame(['1'], $params);
$where = [];
$params = [];
RepoQuery::addEnumFilter($where, $params, 'unknown', [
['aliases' => ['active'], 'sql' => 'status = ?', 'params' => ['1']],
]);
$this->assertSame([], $where);
$this->assertSame([], $params);
}
public function testAddEqualsFilter(): void
{
$where = [];
$params = [];
RepoQuery::addEqualsFilter($where, $params, '', 'foo = ?');
$this->assertSame([], $where);
$this->assertSame([], $params);
RepoQuery::addEqualsFilter($where, $params, 'bar', 'foo = ?');
$this->assertSame(['foo = ?'], $where);
$this->assertSame(['bar'], $params);
}
}

View File

@@ -11,7 +11,7 @@ if (!function_exists(__NAMESPACE__ . '\\t')) {
namespace MintyPHP\Tests\Service;
use MintyPHP\Service\UserService;
use MintyPHP\Service\User\UserService;
use PHPUnit\Framework\TestCase;
use ReflectionMethod;