Created
November 19, 2019 13:14
-
-
Save zonuexe/2fd33134556c355ee4ea3d26282a5277 to your computer and use it in GitHub Desktop.
リフレクションを使った正規表現のためのDocTest
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
namespace PixivTest\Util\RegexPattern; | |
/** | |
* 正規表現のためのDocTest | |
* | |
* {@see \Util_RegexPattern} クラスの定数定義ごとに正規表現をテストする。 | |
* | |
* ## 記法 | |
* | |
* 正規表現が受理する文字列 `@regex\expected` と、受理しない文字列 `@regex\unexpected` の | |
* 二種類のタグを利用する。タグは必ず1行に収まるように記述しなければいけない。 | |
* タグ中に改行を書くことはできないので、そのような文字列を受理する正規表現を書く場合は | |
* DocTestではなく、別途ユニットテストを書いて対応すること。 | |
* | |
* @regex\expected aaaaaaa | |
* @regex\expected bbbbbbb //←ここから行末までは説明 | |
* @regex\expected cccc //←余分な空白をトリムしない("cccc "が検査対象)ので注意 | |
*/ | |
final class DocCommentTest extends \PixivLibTestCase | |
{ | |
/** | |
* @group doctest | |
* @dataProvider dataProvider_test | |
*/ | |
public function test($name, \ReflectionClassConstant $constant, $expected, $subject, $describe) | |
{ | |
$pattern = $constant->getValue(); | |
// TODO: もし必要になることがあったら配列向けにも実装する | |
if (!is_string($pattern)) { | |
throw new \PxvException('このDocTestは配列は未実装です'); | |
} | |
// preg_match() の返り値(0, 1) に変換する | |
$expected_value = ['expected' => 1, 'unexpected' => 0][$expected]; | |
$this->assertSame($expected_value, preg_match($pattern, $subject), $describe); | |
} | |
/** | |
* ジェネレータを使ったデータプロバイダ | |
* | |
* 配列を返すのではなく、DocCommentのパースを継続しながら yield でデータセットを返す | |
* | |
* @see http://php.net/manual/language.generators.overview.php ジェネレータ | |
*/ | |
public function dataProvider_test() | |
{ | |
$ref = new \ReflectionClass(\Util_RegexPattern::class); | |
foreach ($ref->getReflectionConstants() as $constant) { | |
$lines = $constant->getDocComment(); | |
if ($lines === false) { | |
continue; | |
} | |
foreach (explode("\n", $lines) as $line) { | |
$test = self::_getDocTest($constant, $line); | |
if ($test) { | |
yield $test; | |
} | |
} | |
} | |
} | |
/** | |
* DocCommentの行から @regex\expected, unexpected のテスト行を取得する | |
* | |
* @param \ReflectionClassConstant $ref | |
* @param string $input | |
* @return array|false | |
*/ | |
private static function _getDocTest(\ReflectionClassConstant $ref, $input) | |
{ | |
if (!preg_match('#\* @regex\\\\(?<type>expected|unexpected) (?<subject>.+?)(?<describe>(?: //[^/]+?)?)$#', $input, $m)) { | |
return false; | |
} | |
return [ | |
$ref->getName(), | |
$ref, | |
$m['type'], | |
$m['subject'], | |
ltrim($m['describe'], ' //'), | |
]; | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
final class Util_RegexPattern | |
{ | |
/** | |
* @regex\expected ああああ | |
* @regex\expected ゑeeeeee | |
* @regex\unexpected xxxxxx | |
*/ | |
const HIRAGANA_START = '/^[ぁ-ん]/u'; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment