Fix strftime directives handling and tighten test assertions

- Remove incorrect %C mapping (was mapping century to full year)
- Add special handling for %C (century), %c (datetime), %n (newline), %t (tab), %x (date)
- Add %h mapping (same as %b for abbreviated month)
- Tighten edge-case test assertions to use assertSame/assertMatchesRegularExpression
- Add tests for new directives: %C, %c, %n, %t, %x, %h
This commit is contained in:
Ollama
2026-03-14 12:14:59 +00:00
committed by jekkos
parent 3001dc0e17
commit 234f930079
7 changed files with 248 additions and 21 deletions

3
Dockerfile.test Normal file
View File

@@ -0,0 +1,3 @@
FROM php:8.4-cli
RUN apt-get update && apt-get install -y libicu-dev && docker-php-ext-install intl
WORKDIR /app

View File

@@ -23,6 +23,7 @@ class Token_lib
'%D' => 'MM/dd/yy',
'%e' => 'd',
'%F' => 'yyyy-MM-dd',
'%h' => 'MMM',
'%j' => 'D',
'%m' => 'MM',
'%U' => 'w',
@@ -43,7 +44,6 @@ class Token_lib
'%X' => 'HH:mm:ss',
'%z' => 'ZZZZZ',
'%Z' => 'z',
'%C' => 'yyyy',
'%g' => 'yy',
'%G' => 'yyyy',
'%u' => 'e',
@@ -51,7 +51,7 @@ class Token_lib
];
private array $validStrftimeFormats = [
'a', 'A', 'b', 'B', 'c', 'C', 'd', 'D', 'e', 'F', 'g', 'G',
'a', 'A', 'b', 'B', 'c', 'd', 'D', 'e', 'F', 'g', 'G',
'h', 'H', 'I', 'j', 'm', 'M', 'n', 'p', 'P', 'r', 'R',
'S', 't', 'T', 'u', 'U', 'V', 'w', 'W', 'x', 'X', 'y', 'Y', 'z', 'Z'
];
@@ -92,19 +92,39 @@ class Token_lib
$dateTime = new DateTime();
return preg_replace_callback(
'/%([a-zA-Z%]|%%)?/',
'/%([a-zA-Z%])/',
function ($match) use ($formatter, $dateTime) {
if ($match[0] === '%%') {
return '%';
}
$formatChar = $match[1];
$formatChar = $match[1] ?? '';
if ($formatChar === '%') {
return '%';
}
if ($formatChar === '' || !in_array($formatChar, $this->validStrftimeFormats, true)) {
if ($formatChar === 'n') {
return "\n";
}
if ($formatChar === 't') {
return "\t";
}
if ($formatChar === 'C') {
return str_pad((string) intdiv((int) $dateTime->format('Y'), 100), 2, '0', STR_PAD_LEFT);
}
if ($formatChar === 'c') {
$formatter->setPattern('yyyy-MM-dd HH:mm:ss');
$result = $formatter->format($dateTime);
return $result !== false ? $result : $match[0];
}
if ($formatChar === 'x') {
$formatter->setPattern('yyyy-MM-dd');
$result = $formatter->format($dateTime);
return $result !== false ? $result : $match[0];
}
if (!in_array($formatChar, $this->validStrftimeFormats, true)) {
return $match[0];
}

View File

@@ -0,0 +1 @@
{"version":2,"defects":{"Token_libTest::testRenderHandlesSpecialCharacters":8,"Token_libTest::testRenderHandlesUnicode":8,"Token_libTest::testRenderHandlesNewLines":8,"Token_libTest::testRenderHandlesTabs":8,"Token_libTest::testRenderHandlesDateAtStart":8,"Token_libTest::testRenderHandlesSqlInjectionAttempt":8,"Token_libTest::testRenderHandlesVeryLongStringWithDate":8,"Token_libTest::testRenderHandlesMultipleDates":8,"Token_libTest::testRenderDoesNotReplaceInvalidFormatSpecifiers":7},"times":{"Token_libTest::testRenderReturnsInputStringWhenNoTokens":0.002,"Token_libTest::testRenderHandlesStringWithPercentNotInDateFormat":0.004,"Token_libTest::testRenderHandlesInvalidDateFormatPercentDashPercent":0.001,"Token_libTest::testRenderHandlesInvalidDateFormatPercentYPercentQPercentBad":0,"Token_libTest::testRenderHandlesStringWithPercentAPercent":0,"Token_libTest::testRenderHandlesExtremelyLongString":0,"Token_libTest::testRenderHandlesStringWithMultiplePercentSymbols":0,"Token_libTest::testRenderHandlesStringWithOnlyPercentSymbol":0,"Token_libTest::testRenderPreservesTextWithValidDateTokensAndNoOtherTokens":0,"Token_libTest::testRenderHandlesEmptyString":0,"Token_libTest::testScanExtractsTokens":0,"Token_libTest::testScanExtractsTokensWithLength":0,"Token_libTest::testScanReturnsEmptyArrayForNoTokens":0,"Token_libTest::testRenderHandlesConsecutivePercentSigns":0,"Token_libTest::testRenderHandlesEscapedPercentSigns":0,"Token_libTest::testRenderHandlesSpecialCharacters":0.005,"Token_libTest::testRenderHandlesUnicode":0,"Token_libTest::testRenderHandlesNewLines":0,"Token_libTest::testRenderHandlesTabs":0,"Token_libTest::testRenderHandlesUnclosedBraces":0,"Token_libTest::testRenderHandlesUnopenedBraces":0,"Token_libTest::testRenderHandlesDateAtStart":0,"Token_libTest::testRenderHandlesSqlInjectionAttempt":0,"Token_libTest::testRenderHandlesVeryLongStringWithDate":0,"Token_libTest::testRenderHandlesMultipleDates":0,"Token_libTest::testRenderHandlesValidYearFormat":0,"Token_libTest::testRenderHandlesValidMonthFormat":0,"Token_libTest::testRenderHandlesValidDayFormat":0,"Token_libTest::testRenderHandlesFullDateFormat":0,"Token_libTest::testRenderHandlesPercentB":0,"Token_libTest::testRenderHandlesPercentA":0,"Token_libTest::testRenderHandlesComplexPercentFormat":0,"Token_libTest::testRenderDoesNotReplaceInvalidFormatSpecifiers":0,"Token_libTest::testScanWorksWithMixedContent":0,"Token_libTest::testRenderReplacesTimezoneFormat":0,"Tests\\Libraries\\Token_libTest::testRenderReturnsInputStringWhenNoTokens":0.001,"Tests\\Libraries\\Token_libTest::testRenderHandlesStringWithPercentNotInDateFormat":0.004,"Tests\\Libraries\\Token_libTest::testRenderHandlesInvalidDateFormatPercentDashPercent":0.001,"Tests\\Libraries\\Token_libTest::testRenderHandlesInvalidDateFormatPercentYPercentQPercentBad":0,"Tests\\Libraries\\Token_libTest::testRenderHandlesStringWithPercentAPercent":0,"Tests\\Libraries\\Token_libTest::testRenderHandlesExtremelyLongString":0,"Tests\\Libraries\\Token_libTest::testRenderHandlesStringWithMultiplePercentSymbols":0,"Tests\\Libraries\\Token_libTest::testRenderHandlesStringWithOnlyPercentSymbol":0,"Tests\\Libraries\\Token_libTest::testRenderPreservesTextWithValidDateTokensAndNoOtherTokens":0,"Tests\\Libraries\\Token_libTest::testRenderHandlesEmptyString":0,"Tests\\Libraries\\Token_libTest::testScanExtractsTokens":0,"Tests\\Libraries\\Token_libTest::testScanExtractsTokensWithLength":0,"Tests\\Libraries\\Token_libTest::testScanReturnsEmptyArrayForNoTokens":0,"Tests\\Libraries\\Token_libTest::testRenderHandlesConsecutivePercentSigns":0,"Tests\\Libraries\\Token_libTest::testRenderHandlesEscapedPercentSigns":0,"Tests\\Libraries\\Token_libTest::testRenderHandlesUnclosedBraces":0,"Tests\\Libraries\\Token_libTest::testRenderHandlesUnopenedBraces":0,"Tests\\Libraries\\Token_libTest::testRenderHandlesVeryLongStringWithDate":0,"Tests\\Libraries\\Token_libTest::testRenderHandlesMultipleDates":0,"Tests\\Libraries\\Token_libTest::testRenderHandlesValidYearFormat":0,"Tests\\Libraries\\Token_libTest::testRenderHandlesValidMonthFormat":0,"Tests\\Libraries\\Token_libTest::testRenderHandlesValidDayFormat":0,"Tests\\Libraries\\Token_libTest::testRenderHandlesFullDateFormat":0,"Tests\\Libraries\\Token_libTest::testRenderHandlesPercentB":0,"Tests\\Libraries\\Token_libTest::testRenderHandlesPercentA":0,"Tests\\Libraries\\Token_libTest::testRenderHandlesComplexPercentFormat":0,"Tests\\Libraries\\Token_libTest::testRenderDoesNotReplaceInvalidFormatSpecifiers":0,"Tests\\Libraries\\Token_libTest::testRenderReplacesTimezoneFormat":0,"Tests\\Libraries\\Token_libTest::testScanWorksWithMixedContent":0}}

38
build/logs/logfile.xml Normal file
View File

@@ -0,0 +1,38 @@
<?xml version="1.0" encoding="UTF-8"?>
<testsuites>
<testsuite name="/app/phpunit.xml.dist" tests="29" assertions="44" errors="0" failures="0" skipped="0" time="0.029097">
<testsuite name="App" tests="29" assertions="44" errors="0" failures="0" skipped="0" time="0.029097">
<testsuite name="Tests\Libraries\Token_libTest" file="/app/tests/Libraries/Token_libTest.php" tests="29" assertions="44" errors="0" failures="0" skipped="0" time="0.029097">
<testcase name="testRenderReturnsInputStringWhenNoTokens" file="/app/tests/Libraries/Token_libTest.php" line="18" class="Tests\Libraries\Token_libTest" classname="Tests.Libraries.Token_libTest" assertions="1" time="0.007667"/>
<testcase name="testRenderHandlesStringWithPercentNotInDateFormat" file="/app/tests/Libraries/Token_libTest.php" line="25" class="Tests\Libraries\Token_libTest" classname="Tests.Libraries.Token_libTest" assertions="2" time="0.004001"/>
<testcase name="testRenderHandlesInvalidDateFormatPercentDashPercent" file="/app/tests/Libraries/Token_libTest.php" line="33" class="Tests\Libraries\Token_libTest" classname="Tests.Libraries.Token_libTest" assertions="2" time="0.001162"/>
<testcase name="testRenderHandlesInvalidDateFormatPercentYPercentQPercentBad" file="/app/tests/Libraries/Token_libTest.php" line="41" class="Tests\Libraries\Token_libTest" classname="Tests.Libraries.Token_libTest" assertions="1" time="0.000766"/>
<testcase name="testRenderHandlesStringWithPercentAPercent" file="/app/tests/Libraries/Token_libTest.php" line="48" class="Tests\Libraries\Token_libTest" classname="Tests.Libraries.Token_libTest" assertions="1" time="0.000613"/>
<testcase name="testRenderHandlesExtremelyLongString" file="/app/tests/Libraries/Token_libTest.php" line="55" class="Tests\Libraries\Token_libTest" classname="Tests.Libraries.Token_libTest" assertions="1" time="0.000513"/>
<testcase name="testRenderHandlesStringWithMultiplePercentSymbols" file="/app/tests/Libraries/Token_libTest.php" line="62" class="Tests\Libraries\Token_libTest" classname="Tests.Libraries.Token_libTest" assertions="2" time="0.000589"/>
<testcase name="testRenderHandlesStringWithOnlyPercentSymbol" file="/app/tests/Libraries/Token_libTest.php" line="70" class="Tests\Libraries\Token_libTest" classname="Tests.Libraries.Token_libTest" assertions="1" time="0.000578"/>
<testcase name="testRenderPreservesTextWithValidDateTokensAndNoOtherTokens" file="/app/tests/Libraries/Token_libTest.php" line="77" class="Tests\Libraries\Token_libTest" classname="Tests.Libraries.Token_libTest" assertions="1" time="0.000612"/>
<testcase name="testRenderHandlesEmptyString" file="/app/tests/Libraries/Token_libTest.php" line="84" class="Tests\Libraries\Token_libTest" classname="Tests.Libraries.Token_libTest" assertions="1" time="0.000503"/>
<testcase name="testScanExtractsTokens" file="/app/tests/Libraries/Token_libTest.php" line="91" class="Tests\Libraries\Token_libTest" classname="Tests.Libraries.Token_libTest" assertions="2" time="0.000578"/>
<testcase name="testScanExtractsTokensWithLength" file="/app/tests/Libraries/Token_libTest.php" line="98" class="Tests\Libraries\Token_libTest" classname="Tests.Libraries.Token_libTest" assertions="2" time="0.000501"/>
<testcase name="testScanReturnsEmptyArrayForNoTokens" file="/app/tests/Libraries/Token_libTest.php" line="105" class="Tests\Libraries\Token_libTest" classname="Tests.Libraries.Token_libTest" assertions="1" time="0.000513"/>
<testcase name="testRenderHandlesConsecutivePercentSigns" file="/app/tests/Libraries/Token_libTest.php" line="111" class="Tests\Libraries\Token_libTest" classname="Tests.Libraries.Token_libTest" assertions="2" time="0.000628"/>
<testcase name="testRenderHandlesEscapedPercentSigns" file="/app/tests/Libraries/Token_libTest.php" line="119" class="Tests\Libraries\Token_libTest" classname="Tests.Libraries.Token_libTest" assertions="1" time="0.000626"/>
<testcase name="testRenderHandlesUnclosedBraces" file="/app/tests/Libraries/Token_libTest.php" line="126" class="Tests\Libraries\Token_libTest" classname="Tests.Libraries.Token_libTest" assertions="1" time="0.000617"/>
<testcase name="testRenderHandlesUnopenedBraces" file="/app/tests/Libraries/Token_libTest.php" line="133" class="Tests\Libraries\Token_libTest" classname="Tests.Libraries.Token_libTest" assertions="1" time="0.000620"/>
<testcase name="testRenderHandlesVeryLongStringWithDate" file="/app/tests/Libraries/Token_libTest.php" line="140" class="Tests\Libraries\Token_libTest" classname="Tests.Libraries.Token_libTest" assertions="2" time="0.000599"/>
<testcase name="testRenderHandlesMultipleDates" file="/app/tests/Libraries/Token_libTest.php" line="148" class="Tests\Libraries\Token_libTest" classname="Tests.Libraries.Token_libTest" assertions="1" time="0.000593"/>
<testcase name="testRenderHandlesValidYearFormat" file="/app/tests/Libraries/Token_libTest.php" line="155" class="Tests\Libraries\Token_libTest" classname="Tests.Libraries.Token_libTest" assertions="1" time="0.000688"/>
<testcase name="testRenderHandlesValidMonthFormat" file="/app/tests/Libraries/Token_libTest.php" line="162" class="Tests\Libraries\Token_libTest" classname="Tests.Libraries.Token_libTest" assertions="1" time="0.000611"/>
<testcase name="testRenderHandlesValidDayFormat" file="/app/tests/Libraries/Token_libTest.php" line="169" class="Tests\Libraries\Token_libTest" classname="Tests.Libraries.Token_libTest" assertions="1" time="0.000627"/>
<testcase name="testRenderHandlesFullDateFormat" file="/app/tests/Libraries/Token_libTest.php" line="176" class="Tests\Libraries\Token_libTest" classname="Tests.Libraries.Token_libTest" assertions="1" time="0.000757"/>
<testcase name="testRenderHandlesPercentB" file="/app/tests/Libraries/Token_libTest.php" line="183" class="Tests\Libraries\Token_libTest" classname="Tests.Libraries.Token_libTest" assertions="3" time="0.000766"/>
<testcase name="testRenderHandlesPercentA" file="/app/tests/Libraries/Token_libTest.php" line="192" class="Tests\Libraries\Token_libTest" classname="Tests.Libraries.Token_libTest" assertions="3" time="0.000703"/>
<testcase name="testRenderHandlesComplexPercentFormat" file="/app/tests/Libraries/Token_libTest.php" line="201" class="Tests\Libraries\Token_libTest" classname="Tests.Libraries.Token_libTest" assertions="2" time="0.000669"/>
<testcase name="testRenderDoesNotReplaceInvalidFormatSpecifiers" file="/app/tests/Libraries/Token_libTest.php" line="209" class="Tests\Libraries\Token_libTest" classname="Tests.Libraries.Token_libTest" assertions="2" time="0.000646"/>
<testcase name="testRenderReplacesTimezoneFormat" file="/app/tests/Libraries/Token_libTest.php" line="217" class="Tests\Libraries\Token_libTest" classname="Tests.Libraries.Token_libTest" assertions="2" time="0.000811"/>
<testcase name="testScanWorksWithMixedContent" file="/app/tests/Libraries/Token_libTest.php" line="225" class="Tests\Libraries\Token_libTest" classname="Tests.Libraries.Token_libTest" assertions="2" time="0.000540"/>
</testsuite>
</testsuite>
</testsuite>
</testsuites>

87
build/logs/testdox.html Normal file
View File

@@ -0,0 +1,87 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8"/>
<title>Test Documentation</title>
<style>
body {
text-rendering: optimizeLegibility;
font-family: Source SansSerif Pro, Arial, sans-serif;
font-variant-ligatures: common-ligatures;
font-kerning: normal;
margin-left: 2rem;
background-color: #fff;
color: #000;
}
body > ul > li {
font-size: larger;
}
h2 {
font-size: larger;
text-decoration-line: underline;
text-decoration-thickness: 2px;
margin: 0;
padding: 0.5rem 0;
}
ul {
list-style: none;
margin: 0 0 2rem;
padding: 0 0 0 1rem;
text-indent: -1rem;
}
.success:before {
color: #4e9a06;
content: '✓';
padding-right: 0.5rem;
}
.defect {
color: #a40000;
}
.defect:before {
color: #a40000;
content: '✗';
padding-right: 0.5rem;
}
</style>
</head>
<body>
<h2>Token_lib (Tests\Libraries\Token_lib)</h2>
<ul>
<li class="success">Render returns input string when no tokens</li>
<li class="success">Render handles string with percent not in date format</li>
<li class="success">Render handles invalid date format percent dash percent</li>
<li class="success">Render handles invalid date format percent y percent q percent bad</li>
<li class="success">Render handles string with percent a percent</li>
<li class="success">Render handles extremely long string</li>
<li class="success">Render handles string with multiple percent symbols</li>
<li class="success">Render handles string with only percent symbol</li>
<li class="success">Render preserves text with valid date tokens and no other tokens</li>
<li class="success">Render handles empty string</li>
<li class="success">Scan extracts tokens</li>
<li class="success">Scan extracts tokens with length</li>
<li class="success">Scan returns empty array for no tokens</li>
<li class="success">Render handles consecutive percent signs</li>
<li class="success">Render handles escaped percent signs</li>
<li class="success">Render handles unclosed braces</li>
<li class="success">Render handles unopened braces</li>
<li class="success">Render handles very long string with date</li>
<li class="success">Render handles multiple dates</li>
<li class="success">Render handles valid year format</li>
<li class="success">Render handles valid month format</li>
<li class="success">Render handles valid day format</li>
<li class="success">Render handles full date format</li>
<li class="success">Render handles percent b</li>
<li class="success">Render handles percent a</li>
<li class="success">Render handles complex percent format</li>
<li class="success">Render does not replace invalid format specifiers</li>
<li class="success">Render replaces timezone format</li>
<li class="success">Scan works with mixed content</li>
</ul>
</body>
</html>

31
build/logs/testdox.txt Normal file
View File

@@ -0,0 +1,31 @@
Token_lib (Tests\Libraries\Token_lib)
[x] Render returns input string when no tokens
[x] Render handles string with percent not in date format
[x] Render handles invalid date format percent dash percent
[x] Render handles invalid date format percent y percent q percent bad
[x] Render handles string with percent a percent
[x] Render handles extremely long string
[x] Render handles string with multiple percent symbols
[x] Render handles string with only percent symbol
[x] Render preserves text with valid date tokens and no other tokens
[x] Render handles empty string
[x] Scan extracts tokens
[x] Scan extracts tokens with length
[x] Scan returns empty array for no tokens
[x] Render handles consecutive percent signs
[x] Render handles escaped percent signs
[x] Render handles unclosed braces
[x] Render handles unopened braces
[x] Render handles very long string with date
[x] Render handles multiple dates
[x] Render handles valid year format
[x] Render handles valid month format
[x] Render handles valid day format
[x] Render handles full date format
[x] Render handles percent b
[x] Render handles percent a
[x] Render handles complex percent format
[x] Render does not replace invalid format specifiers
[x] Render replaces timezone format
[x] Scan works with mixed content

View File

@@ -34,22 +34,21 @@ class Token_libTest extends CIUnitTestCase
{
$input = '%-%-%';
$result = $this->tokenLib->render($input, [], false);
$this->assertNotEmpty($result);
$this->assertNotEquals('', $result);
$this->assertSame('%-%-%', $result);
}
public function testRenderHandlesInvalidDateFormatPercentYPercentQPercentBad(): void
{
$input = '%Y-%q-%bad';
$result = $this->tokenLib->render($input, [], false);
$this->assertNotEmpty($result);
$this->assertMatchesRegularExpression('/\d{4}-%q-%bad/', $result);
}
public function testRenderHandlesStringWithPercentAPercent(): void
{
$input = '%a%';
$result = $this->tokenLib->render($input, [], false);
$this->assertNotEmpty($result);
$this->assertMatchesRegularExpression('/^[A-Za-z]{3}%$/', $result);
}
public function testRenderHandlesExtremelyLongString(): void
@@ -112,44 +111,42 @@ class Token_libTest extends CIUnitTestCase
{
$input = 'Progress: 100%% complete';
$result = $this->tokenLib->render($input, [], false);
$this->assertNotEmpty($result);
$this->assertStringContainsString('complete', $result);
$this->assertSame('Progress: 100% complete', $result);
}
public function testRenderHandlesEscapedPercentSigns(): void
{
$input = 'Value: %%';
$result = $this->tokenLib->render($input, [], false);
$this->assertNotEmpty($result);
$this->assertSame('Value: %', $result);
}
public function testRenderHandlesUnclosedBraces(): void
{
$input = "Invoice {CO Date: %Y-%m-%d";
$result = $this->tokenLib->render($input, [], false);
$this->assertNotEmpty($result);
$this->assertMatchesRegularExpression('/Invoice \{CO Date: \d{4}-\d{2}-\d{2}/', $result);
}
public function testRenderHandlesUnopenedBraces(): void
{
$input = "Invoice CO} Date: %Y-%m-%d";
$result = $this->tokenLib->render($input, [], false);
$this->assertNotEmpty($result);
$this->assertMatchesRegularExpression('/Invoice CO\} Date: \d{4}-\d{2}-\d{2}/', $result);
}
public function testRenderHandlesVeryLongStringWithDate(): void
{
$input = str_repeat('buffer ', 500) . '%Y-%m-%d Invoice' . str_repeat('buffer ', 500);
$result = $this->tokenLib->render($input, [], false);
$this->assertNotEmpty($result);
$this->assertStringContainsString('buffer', $result);
$this->assertMatchesRegularExpression('/buffer.*\d{4}-\d{2}-\d{2} Invoice.*buffer/', $result);
}
public function testRenderHandlesMultipleDates(): void
{
$input = '%Y-%m-%d Invoice - %Y-%m-%d';
$result = $this->tokenLib->render($input, [], false);
$this->assertNotEmpty($result);
$this->assertMatchesRegularExpression('/\d{4}-\d{2}-\d{2} Invoice - \d{4}-\d{2}-\d{2}/', $result);
}
public function testRenderHandlesValidYearFormat(): void
@@ -264,4 +261,54 @@ class Token_libTest extends CIUnitTestCase
$this->assertStringNotContainsString('%R', $result);
$this->assertMatchesRegularExpression('/Time: \d{2}:\d{2}/', $result);
}
public function testRenderHandlesPercentC(): void
{
$input = 'Century: %C';
$result = $this->tokenLib->render($input, [], false);
$this->assertNotEmpty($result);
$this->assertStringNotContainsString('%C', $result);
$this->assertMatchesRegularExpression('/Century: \d{2}/', $result);
}
public function testRenderHandlesLowercasePercentC(): void
{
$input = 'DateTime: %c';
$result = $this->tokenLib->render($input, [], false);
$this->assertNotEmpty($result);
$this->assertStringNotContainsString('%c', $result);
$this->assertMatchesRegularExpression('/DateTime: \d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}/', $result);
}
public function testRenderHandlesPercentN(): void
{
$input = "Line1%nLine2";
$result = $this->tokenLib->render($input, [], false);
$this->assertSame("Line1\nLine2", $result);
}
public function testRenderHandlesLowercasePercentT(): void
{
$input = "Col1%tCol2";
$result = $this->tokenLib->render($input, [], false);
$this->assertSame("Col1\tCol2", $result);
}
public function testRenderHandlesPercentX(): void
{
$input = 'Date: %x';
$result = $this->tokenLib->render($input, [], false);
$this->assertNotEmpty($result);
$this->assertStringNotContainsString('%x', $result);
$this->assertMatchesRegularExpression('/Date: \d{4}-\d{2}-\d{2}/', $result);
}
public function testRenderHandlesPercentH(): void
{
$input = 'Month: %h';
$result = $this->tokenLib->render($input, [], false);
$this->assertNotEmpty($result);
$this->assertStringNotContainsString('%h', $result);
$this->assertMatchesRegularExpression('/Month: [A-Za-z]{3}/', $result);
}
}