diff --git a/bin/unipoints b/bin/unipoints index 18eddd2..24e5842 100755 --- a/bin/unipoints +++ b/bin/unipoints @@ -157,6 +157,10 @@ function main(array $args): int } try { + mb_regex_encoding('UTF-8'); + ini_set('mbstring.script_encoding', 'pass'); + mb_internal_encoding('UTF-8'); + mb_substitute_character('none'); $exitStatus = main($argv); } catch (UserMessageException $x) { echo trim($x->getMessage()), "\n"; diff --git a/test/bootstrap.php b/test/bootstrap.php index c25026e..02e3a24 100644 --- a/test/bootstrap.php +++ b/test/bootstrap.php @@ -4,6 +4,11 @@ use MLUnipoints\Build\FilesystemCache; +mb_regex_encoding('UTF-8'); +ini_set('mbstring.script_encoding', 'pass'); +mb_internal_encoding('UTF-8'); +mb_substitute_character('none'); + require_once __DIR__ . '/../vendor/autoload.php'; define('MLUNIPOINTS_TEST_PROJECTROOT', rtrim(str_replace(DIRECTORY_SEPARATOR, '/', realpath(__DIR__ . '/..')), '/')); diff --git a/test/tests/BlockEnumTest.php b/test/tests/BlockEnumTest.php index da37f96..eb672c4 100644 --- a/test/tests/BlockEnumTest.php +++ b/test/tests/BlockEnumTest.php @@ -59,6 +59,7 @@ public function testEnumeratedCases(): void } } } + /** * @dataProvider provideEnumCases */ diff --git a/test/tests/CodepointEnumTest.php b/test/tests/CodepointEnumTest.php new file mode 100644 index 0000000..b5e47d6 --- /dev/null +++ b/test/tests/CodepointEnumTest.php @@ -0,0 +1,124 @@ +name; + if (enum_exists($class)) { + $result[] = [$class, $block]; + } + } + return $result; + } + + /** + * @dataProvider provideEnumClasses + */ + public function testUnicodeInfoAttribute(string $className, ?Block $block): void + { + $info = UnicodeInfo::from($className); + $this->assertInstanceOf(UnicodeInfo::class, $info); + $class = new ReflectionEnum($className); + $enumAttributes = $class->getAttributes(UnicodeInfo::class); + $this->assertCount(1, $enumAttributes); + $this->assertEquals($info, $enumAttributes[0]->newInstance()); + $this->assertMatchesRegularExpression('/^[1-9]\d*(\.\d+)*$/', $info->unicodeVersion); + } + + /** + * @dataProvider provideEnumClasses + */ + public function testEnumType(string $className, ?Block $block): void + { + $planeClass = new ReflectionEnum($className); + $type = $planeClass->getBackingType(); + $this->assertNotNull($type); + $this->assertTrue($type->isBuiltin()); + $this->assertSame('string', $type->getName()); + } + + public function testEnumeratedCasesList(): void + { + $cases = self::provideEnumClasses(); + $this->assertGreaterThan(1, count($cases)); + $this->assertNull($cases[0][1]); + $this->assertInstanceOf(Block::class, $cases[1][1]); + } + + /** + * @dataProvider provideEnumClasses + */ + public function testInfos(string $className, ?Block $block): void + { + foreach (self::listEnumCases($className, $block) as [$case, $previousCase]) { + $this->testInfo($case, $previousCase, $block); + } + } + + private function testInfo(BackedEnum $case, ?BackedEnum $previousCase, ?Block $block): void + { + $info = CodepointInfo::from($case); + $this->assertInstanceOf(CodepointInfo::class, $info); + $caseReflection = new ReflectionEnumBackedCase($case, $case->name); + $caseAttributes = $caseReflection->getAttributes(CodepointInfo::class); + $this->assertCount(1, $caseAttributes); + $this->assertEquals($info, $caseAttributes[0]->newInstance()); + $this->assertGreaterThanOrEqual(0, $info->id); + $this->assertNotSame('', $info->name); + if ($info->category !== Category::Surrogate) { + $this->assertSame(1, mb_strlen($case->value), "mb_strlen of codepoint {$info->id} ('{$case->value}')"); + } + $categoryInfo = CategoryInfo::from($info->category); + $this->assertSame([], $categoryInfo->childCategories); + if ($block === null) { + $this->assertInstanceOf(Codepoint::class, $case); + $this->assertInstanceOf(Block::class, $info->block); + if ($previousCase !== null) { + $this->assertInstanceOf(Codepoint::class, $previousCase); + } + } else { + $this->assertInstanceOf(Codepoint::class . '\\' . $block->name, $case); + $this->assertNull($info->block); + if ($previousCase !== null) { + $this->assertInstanceOf(Codepoint::class . '\\' . $block->name, $previousCase); + } + } + if ($previousCase !== null) { + $previousInfo = CodepointInfo::from($previousCase); + $this->assertGreaterThan($previousInfo->id, $info->id); + } + } + + private static function listEnumCases(string $className, ?Block $block): Generator + { + $class = new ReflectionEnum($className); + $previousCase = null; + $index = 0; + foreach ($class->getCases() as $caseClass) { + $case = $caseClass->getValue(); + yield $index++ => [$case, $previousCase]; + $previousCase = $case; + } + } +}