%PDF- %PDF-
| Direktori : /www/varak.net/nextcloud.varak.net/apps_old/apps/bookmarks/vendor/rowbot/idna/tests/ |
| Current File : /www/varak.net/nextcloud.varak.net/apps_old/apps/bookmarks/vendor/rowbot/idna/tests/IdnaV2Test.php |
<?php
declare(strict_types=1);
namespace Rowbot\Idna\Test;
use ReflectionClass;
use Rowbot\Idna\Idna;
use function array_filter;
use function array_flip;
use function is_array;
use function sprintf;
use function strncmp;
use const ARRAY_FILTER_USE_KEY;
class IdnaV2Test extends IdnaV2TestCase
{
private const DEFAULT_OPTIONS = [
'CheckHyphens' => true,
'CheckBidi' => true,
'CheckJoiners' => true,
'UseSTD3ASCIIRules' => true,
'Transitional_Processing' => false,
'VerifyDnsLength' => true,
];
/**
* @var array<int, string>
*/
protected static $errorMap;
public static function setUpBeforeClass(): void
{
if (isset(self::$errorMap)) {
return;
}
$reflection = new ReflectionClass(Idna::class);
$errors = array_filter($reflection->getConstants(), static function (string $name): bool {
return strncmp($name, 'ERROR_', 6) === 0;
}, ARRAY_FILTER_USE_KEY);
self::$errorMap = array_flip($errors);
}
/**
* @return array<int, array<int, string>>
*/
public function getData(): array
{
return $this->loadTestData(Idna::UNICODE_VERSION);
}
/**
* @dataProvider getData
*/
public function testToUnicode(
string $source,
string $toUnicode,
string $toUnicodeStatus,
string $toAsciiN,
string $toAsciiNStatus,
string $toAsciiT,
string $toAsciiTStatus
): void {
[
$toUnicode,
$toUnicodeStatus,
$toAsciiN,
$toAsciiNStatus,
$toAsciiT,
$toAsciiTStatus,
] = $this->translate($source, $toUnicode, $toUnicodeStatus, $toAsciiN, $toAsciiNStatus, $toAsciiT, $toAsciiTStatus);
$result = Idna::toUnicode($source, self::DEFAULT_OPTIONS);
self::assertSame($toUnicode, $result->getDomain());
if ($toUnicodeStatus === []) {
self::assertFalse($result->hasErrors(), sprintf(
'Expected no errors, but found %s.',
$this->containedErrors($result->getErrors())
));
} else {
self::assertTrue($result->hasErrors(), sprintf(
'Expected to find %s, but found %s',
$this->expectedErrors($toUnicodeStatus),
$this->containedErrors($result->getErrors())
));
}
}
/**
* @dataProvider getData
*/
public function testToAsciiNonTransitional(
string $source,
string $toUnicode,
string $toUnicodeStatus,
string $toAsciiN,
string $toAsciiNStatus,
string $toAsciiT,
string $toAsciiTStatus
): void {
[
$toUnicode,
$toUnicodeStatus,
$toAsciiN,
$toAsciiNStatus,
$toAsciiT,
$toAsciiTStatus,
] = $this->translate($source, $toUnicode, $toUnicodeStatus, $toAsciiN, $toAsciiNStatus, $toAsciiT, $toAsciiTStatus);
$result = Idna::toAscii($source, self::DEFAULT_OPTIONS);
if ($toAsciiNStatus === []) {
self::assertSame($toAsciiN, $result->getDomain());
self::assertFalse($result->hasErrors(), sprintf(
'Expected no errors, but found %s.',
$this->containedErrors($result->getErrors())
));
} else {
self::assertTrue($result->hasErrors(), sprintf(
'Expected %s, but found no errors.',
$this->expectedErrors($toAsciiTStatus)
));
}
}
/**
* @dataProvider getData
*/
public function testToAsciiTransitional(
string $source,
string $toUnicode,
string $toUnicodeStatus,
string $toAsciiN,
string $toAsciiNStatus,
string $toAsciiT,
string $toAsciiTStatus
): void {
[
$toUnicode,
$toUnicodeStatus,
$toAsciiN,
$toAsciiNStatus,
$toAsciiT,
$toAsciiTStatus,
] = $this->translate($source, $toUnicode, $toUnicodeStatus, $toAsciiN, $toAsciiNStatus, $toAsciiT, $toAsciiTStatus);
$options = self::DEFAULT_OPTIONS;
$options['Transitional_Processing'] = true;
$result = Idna::toAscii($source, $options);
// There is currently a bug in the test data, where it is expected that the following 2
// source strings result in an empty string. However, due to the way the test files are setup
// it currently isn't possible to represent an empty string as an expected value. So, we
// skip these 2 problem tests. I have notified the Unicode Consortium about this and they
// have passed the information along to the spec editors.
if ($source === "\u{200C}" || $source === "\u{200D}") {
$toAsciiT = '';
}
if ($toAsciiTStatus === []) {
self::assertSame($toAsciiT, $result->getDomain());
self::assertFalse($result->hasErrors(), sprintf(
'Expected no errors, but found %s.',
$this->containedErrors($result->getErrors())
));
} else {
self::assertTrue($result->hasErrors(), sprintf(
'Expected %s, but found no errors.',
$this->expectedErrors($toAsciiTStatus)
));
}
}
public function assertErrors(array $expectedErrors, int $errors): void
{
foreach ($expectedErrors as $errorCode) {
if (is_array($errorCode)) {
self::assertTrue($this->matchErrors($errorCode, $errors));
continue;
}
self::assertTrue(
($errors & $errorCode) !== 0,
sprintf(
'Expected %s (%d), but only found %s.',
self::$errorMap[$errorCode],
$errorCode,
$this->containedErrors($errors)
)
);
}
}
public function expectedErrors(array $expectedErrors): string
{
$message = '';
foreach ($expectedErrors as $i => $errorCode) {
if (is_array($errorCode)) {
$message .= '(';
foreach ($errorCode as $j => $error) {
if ($j > 0) {
$message .= ' OR ';
}
$message .= sprintf('%s (%d)', self::$errorMap[$error], $error);
}
$message .= ')';
} else {
if ($i > 0) {
$message .= ' | ';
}
$message .= sprintf('%s (%d)', self::$errorMap[$errorCode], $errorCode);
}
}
return $message;
}
public function containedErrors(int $errors): string
{
if ($errors === 0) {
return 'no errors';
}
$out = '';
$count = 0;
foreach (self::$errorMap as $code => $name) {
if (($errors & $code) !== 0) {
if ($count++ > 0) {
$out .= ' | ';
}
$out .= sprintf('%s (%d)', $name, $code);
}
}
return $out;
}
public function matchErrors(array $potentialErrors, int $errors): bool
{
foreach ($potentialErrors as $error) {
if (($errors & $error) !== 0) {
return true;
}
}
return false;
}
}