139 lines
6.0 KiB
PHP
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);
|
|
}
|
|
}
|
|
}
|