ldc-arcadia-api/tests/Unit/Shared/Helpers/StringEncoderTest.php

115 lines
4.5 KiB
PHP
Raw Permalink Normal View History

<?php
declare(strict_types=1);
namespace Tests\Unit\Shared\Helpers;
use PHPUnit\Framework\TestCase;
use Shared\Helpers\StringEncoder;
covers(StringEncoder::class);
uses(TestCase::class);
describe('StringEncoder Unit Tests', function (): void {
it('prevents direct instantiation', function (): void {
$reflection = new \ReflectionClass(StringEncoder::class);
expect(fn () => $reflection->newInstance())
->toThrow(\ReflectionException::class);
});
describe('toUtf8', function (): void {
it('returns empty string for empty input', function (): void {
expect(StringEncoder::toUtf8('', 'UTF-8'))->toBe('')
->and(StringEncoder::toUtf8('', 'Windows-1252'))->toBe('');
});
it('passes valid UTF-8 through unchanged', function (): void {
$utf8 = 'Émincés & Rôti de poulet fermier';
expect(StringEncoder::toUtf8($utf8, 'UTF-8'))->toBe($utf8);
});
it('converts Windows-1252 special characters to UTF-8', function (): void {
// 0x80 (€), 0x8C (Œ), 0x9C (œ), 0x92 (’)
$win1252 = "\x80 50 \x8Cuf \x9Cuf l\x92arbre";
$expected = '€ 50 Œuf œuf l’arbre';
expect(StringEncoder::toUtf8($win1252, 'Windows-1252'))->toBe($expected);
});
it('converts ISO-8859-15 specific characters to UTF-8', function (): void {
// 0xA4 (€ in Latin-9), 0xBC (Œ), 0xBD (œ)
$latin9 = "\xA4 50 \xBCuf \xBDuf";
$expected = '€ 50 Œuf œuf';
expect(StringEncoder::toUtf8($latin9, 'ISO-8859-15'))->toBe($expected);
});
it('supports encoding aliases case-insensitively', function (string $alias): void {
$input = "\xE9"; // é in Latin-1/Win-1252
expect(StringEncoder::toUtf8($input, $alias))->toBe('é');
})->with(['windows-1252', 'WIN1252', 'cp1252', 'latin1', 'latin-1', 'iso-8859-1']);
it('strips UTF-8 BOM when stripBom is true', function (): void {
$withBom = "\xEF\xBB\xBFHello World";
expect(StringEncoder::toUtf8($withBom, 'UTF-8', stripBom: true))->toBe('Hello World')
->and(StringEncoder::toUtf8($withBom, 'UTF-8', stripBom: false))->toBe($withBom);
});
it('throws ValueError for unsupported encoding', function (): void {
expect(fn () => StringEncoder::toUtf8('test', 'Shift-JIS'))
->toThrow(\ValueError::class);
});
it('throws ValueError for invalid UTF-8 in toUtf8 with UTF-8 encoding', function (): void {
$invalidUtf8 = "\xC3\x28"; // Invalid UTF-8 sequence
expect(fn () => StringEncoder::toUtf8($invalidUtf8, 'UTF-8'))
->toThrow(\ValueError::class);
});
});
describe('detectAndConvertToUtf8', function (): void {
it('returns empty string for empty input', function (): void {
expect(StringEncoder::detectAndConvertToUtf8(''))->toBe('');
});
it('preserves valid UTF-8 without re-encoding', function (): void {
$utf8 = 'Volaille rôti bio';
expect(StringEncoder::detectAndConvertToUtf8($utf8))->toBe($utf8);
});
it('converts non-UTF8 strings using fallback encoding', function (): void {
// Non-UTF-8: "é" in Windows-1252 is 0xE9
$win1252 = "R\xE9gal du Volailler";
expect(StringEncoder::detectAndConvertToUtf8($win1252, 'Windows-1252'))->toBe('Régal du Volailler');
});
it('throws ValueError when fallbackEncoding is UTF-8', function (): void {
expect(fn () => StringEncoder::detectAndConvertToUtf8('test', 'UTF-8'))
->toThrow(\ValueError::class);
});
});
describe('arrayToUtf8', function (): void {
it('converts an array of strings to UTF-8', function (): void {
$inputs = ["\xE9", "\xE0", "\xE8"];
$expected = ['é', 'à', 'è'];
expect(StringEncoder::arrayToUtf8($inputs, 'Windows-1252'))->toBe($expected);
});
});
describe('supportedEncodings', function (): void {
it('returns list of all supported canonical and alias encodings', function (): void {
$encodings = StringEncoder::supportedEncodings();
expect($encodings)->toContain('UTF-8')
->and($encodings)->toContain('Windows-1252')
->and($encodings)->toContain('ISO-8859-15')
->and($encodings)->toContain('latin1')
->and($encodings)->toContain('cp1252');
});
});
});