Files
luxtools-plugin/_test/ChronoIDTest.php
2026-02-16 13:39:26 +01:00

139 lines
6.0 KiB
PHP

<?php
namespace dokuwiki\plugin\luxtools\test;
use dokuwiki\plugin\luxtools\ChronoID;
use DokuWikiTest;
require_once(__DIR__ . '/../autoload.php');
/**
* Chronological ID helper tests.
*
* @group plugin_luxtools
* @group plugins
*/
class ChronoIDTest extends DokuWikiTest
{
protected function assertBool(bool $expected, bool $actual, string $message): void
{
if ($expected !== $actual) {
throw new \Exception($message);
}
}
protected function assertStringOrNull(?string $expected, ?string $actual, string $message): void
{
if ($expected !== $actual) {
throw new \Exception($message . ' expected=' . var_export($expected, true) . ' actual=' . var_export($actual, true));
}
}
public function testIsIsoDateValidCases(): void
{
$valid = [
'2024-10-24',
'2024-02-29',
];
foreach ($valid as $date) {
$this->assertBool(true, ChronoID::isIsoDate($date), 'Expected valid ISO date: ' . $date);
}
}
public function testIsIsoDateInvalidCases(): void
{
$invalid = [
'2023-02-29',
'2024-13-01',
'2024-00-10',
'24-10-2024',
'2024/10/24',
'2024-10-24 12:00:00',
'2024-10-24T12:00:00',
'0000-01-01',
];
foreach ($invalid as $date) {
$this->assertBool(false, ChronoID::isIsoDate($date), 'Expected invalid ISO date: ' . $date);
}
}
public function testDateToDayId(): void
{
$this->assertStringOrNull('chronological:2024:10:24', ChronoID::dateToDayId('2024-10-24'), 'dateToDayId failed');
$this->assertStringOrNull('journal:chrono:2024:10:24', ChronoID::dateToDayId('2024-10-24', 'journal:chrono'), 'dateToDayId with custom namespace failed');
$this->assertStringOrNull(null, ChronoID::dateToDayId('2024-10-24T12:00:00'), 'datetime should be rejected');
$this->assertStringOrNull(null, ChronoID::dateToDayId('2024-13-01'), 'invalid month should be rejected');
$this->assertStringOrNull(null, ChronoID::dateToDayId('2024-10-24', ''), 'empty namespace should be rejected');
$this->assertStringOrNull(null, ChronoID::dateToDayId('2024-10-24', 'bad namespace!'), 'invalid namespace should be rejected');
}
public function testCanonicalIdChecks(): void
{
$this->assertBool(true, ChronoID::isDayId('chronological:2024:10:24'), 'valid day ID should be accepted');
$this->assertBool(true, ChronoID::isMonthId('chronological:2024:10'), 'valid month ID should be accepted');
$this->assertBool(true, ChronoID::isYearId('chronological:2024'), 'valid year ID should be accepted');
$this->assertBool(false, ChronoID::isDayId('2024:10:24'), 'missing namespace should be rejected as day ID');
$this->assertBool(false, ChronoID::isDayId('chronological:2024-10-24'), 'hyphen date in ID should be rejected as day ID');
$this->assertBool(false, ChronoID::isDayId('chronological:2023:02:29'), 'invalid Gregorian day should be rejected');
$this->assertBool(false, ChronoID::isMonthId('chronological:2024:13'), 'invalid month 13 should be rejected');
$this->assertBool(false, ChronoID::isMonthId('chronological:2024:00'), 'invalid month 00 should be rejected');
$this->assertBool(false, ChronoID::isMonthId('chronological:2024-10'), 'invalid month format should be rejected');
$this->assertBool(false, ChronoID::isYearId('chronological:0000'), 'year 0000 should be rejected');
$this->assertBool(false, ChronoID::isYearId('chronological:24'), 'short year should be rejected');
$this->assertBool(false, ChronoID::isYearId('chronological:2024:10'), 'month ID should not pass as year ID');
}
public function testConversions(): void
{
$this->assertStringOrNull('chronological:2024:10', ChronoID::dayIdToMonthId('chronological:2024:10:24'), 'dayIdToMonthId failed');
$this->assertStringOrNull('chronological:2024', ChronoID::monthIdToYearId('chronological:2024:10'), 'monthIdToYearId failed');
$this->assertStringOrNull(null, ChronoID::dayIdToMonthId('chronological:2024:13:24'), 'invalid day ID should map to null month ID');
$this->assertStringOrNull(null, ChronoID::dayIdToMonthId('chronological:2024:10'), 'month ID should not map via dayIdToMonthId');
$this->assertStringOrNull(null, ChronoID::monthIdToYearId('chronological:2024:13'), 'invalid month ID should map to null year ID');
$this->assertStringOrNull(null, ChronoID::monthIdToYearId('chronological:2024:10:24'), 'day ID should not map via monthIdToYearId');
}
/**
* Integration-style smoke test for canonical ID matrix acceptance/rejection.
*/
public function testCanonicalPageIdSmokeMatrix(): void
{
$accepted = [
['day', 'chronological:2024:10:24'],
['month', 'chronological:2024:10'],
['year', 'chronological:2024'],
];
foreach ($accepted as [$kind, $id]) {
if ($kind === 'day') {
$this->assertBool(true, ChronoID::isDayId($id), 'Expected accepted day ID: ' . $id);
} elseif ($kind === 'month') {
$this->assertBool(true, ChronoID::isMonthId($id), 'Expected accepted month ID: ' . $id);
} else {
$this->assertBool(true, ChronoID::isYearId($id), 'Expected accepted year ID: ' . $id);
}
}
$rejected = [
'2024:10:24',
'chronological:2024-10-24',
'chronological:2024:13:01',
'chronological:2024:00',
'chronological:0000',
];
foreach ($rejected as $id) {
$this->assertBool(false, ChronoID::isDayId($id), 'Unexpected day ID acceptance: ' . $id);
$this->assertBool(false, ChronoID::isMonthId($id), 'Unexpected month ID acceptance: ' . $id);
$this->assertBool(false, ChronoID::isYearId($id), 'Unexpected year ID acceptance: ' . $id);
}
}
}