* @copyright 2021 smiley * @license MIT */ namespace chillerlan\QRCodeTest\Data; use chillerlan\QRCode\Data\Hanzi; use chillerlan\QRCode\Data\QRDataModeInterface; use PHPUnit\Framework\Attributes\DataProvider; use PHPUnit\Framework\Attributes\Group; use Generator, Throwable; use function bin2hex, chr, defined, sprintf; /** * Tests the Hanzi/GB2312 class */ final class HanziTest extends DataInterfaceTestAbstract{ protected const testData = '无可奈何燃花作香'; protected static function getDataModeInterface(string $data):QRDataModeInterface{ return new Hanzi($data); } /** * isGB2312() should pass on Hanzi/GB2312 characters and fail on everything else * * @phpstan-return array */ public static function stringValidateProvider():array{ return [ ['原神', true], ['ABC', false], ['123', false], ['无可奈何燃花作香', true], // https://genshin-impact.fandom.com/wiki/Floral_Incense ['無可奈何燃花作香', false], // same as above in traditional Chinese ['꽃잎 향초의 기도', false], // same as above in Korean ]; } /** * lists all characters in the valid GB2312 range */ public static function hanziProvider():Generator{ for($byte1 = 0xa1; $byte1 < 0xf8; $byte1++){ if($byte1 > 0xa9 && $byte1 < 0xb0){ continue; } for($byte2 = 0xa1; $byte2 < 0xff; $byte2++){ $chr = mb_convert_encoding(chr($byte1).chr($byte2), 'UTF-8', Hanzi::ENCODING); if($chr === '?'){ // skip unknown glyphs continue; } yield sprintf('0x%X', (($byte1 << 8) | $byte2)) => [$chr]; } } } #[Group('slow')] #[DataProvider('hanziProvider')] public function testValidateGB2312(string $chr):void{ // we may run into several issues due to encoding detection failures try{ $this::assertTrue(Hanzi::validateString($chr)); } catch(Throwable){ /** @noinspection PhpUndefinedConstantInspection - see phpunit.xml.dist */ if(defined('TEST_IS_CI') && TEST_IS_CI === true){ $this::markTestSkipped(); } $this::markTestSkipped(sprintf( 'invalid glyph: %s => %s', bin2hex(mb_convert_encoding($chr, Hanzi::ENCODING, 'UTF-8')), $chr, )); } } }