概要
PHPatでアーキテクチャテストを実装する際、Selector::classnamme(正規表現, true);
で依存してはいけないクラスを指定します。
そもそも正規表現似関しての知見が浅く、ファイルのパス指定にかなり苦戦してしまいました。
自分なりに検証を行いたどり着いた、正規表現でパスを指定する方法をご紹介いたします。
正規表現でパスを指定する方法
PHPatではアーキテクチャルールを指定するクラスを作成して、そのクラスでルールを記述します。
ルールには依存してはいけないクラスを指定します。
ただ、このクラス指定で正規表現が正しくない場合(たとえそのクラスが存在しなくても)
そのクラスに依存していないということになり、テストに通ってしまいます。
つまり、正規表現が正しく指定されていないと、テストの意味をなさないということです。
preg_match関数を使う
そこで今回はPHPのpreg_match関数を使って正規表現が正しいかを確認しました。
preg_match(正規表現, 文字列);
第1引数に正規表現、第2引数には文字列を指定し、正規表現が正しい場合にtrueを返します。
Laravelのコントローラの正規表現を正しく指定した場合
正規表現1/^ $/
Laravelのコントローラを指定する正規表現
$path = "app/Http/Controller";
$pattern = "/^app\/Http\/Controller$/";
$result = preg_match($pattern, $path);
var_dump((bool)$result);// true
$path = "{数字}/{数字}/file";
$pattern = "/^([0-9]+)\/([0-9]+)\/file$/";
$result = preg_match($pattern, $path);
var_dump((bool)$result);// true
正規表現2 ?=
ある特定の文字を含む正規表現
$path = "/Users";
$pattern = "/^(?=.*ser).*$/";
$result = preg_match($pattern, $path);
var_dump((bool)$result); //tru
正規表現3 ?!
ある特定の文字以外の正規表現
$path = "/Users";
$pattern = "/^(?!.*ser).*$/";
$result = preg_match($pattern, $path);
var_dump((bool)$result);// false
正規表現4 [^\\\\]+
指定がないときの正規表現
$path = "/app/app/Http/Controllers/Controller.php";
$pattern = "/^\/app\/app\/Http\/[^\\\\]+\/(?=Controller)(?:[^\\\\]+)?$/";
//Controllersのディレクトリ指定が[^\\\\]+
//.phpは?:[^\\\\]+
$result = preg_match($pattern, $path);
var_dump((bool)$result); //true
$path = "/app/app/Http/Controllers/Controller.php";
$pattern = "/^\/app\/app\/Http\/[^\\\\]+\/(?!Controller)(?:[^\\\\]+)?$/";
$result = preg_match($pattern, $path);
var_dump((bool)$result); //false
正規表現5 |
複数指定するときの正規表現
$path = "/app/packages/Domain/Sample/Entity.php";
//Entity
$pattern = "/^\/app\/packages\/Domain\/[^\\\\]+\/(?=Entity|ValueObject)(?:[^\\\\]+)?$/";
//EntityとValueObjectの2つを指定
$result = preg_match($pattern, $path);
var_dump((bool)$result); //true
$path = "/app/packages/Domain/Sample/ValueObject.php";
//ValueObject
$pattern = "/^\/app\/packages\/Domain\/[^\\\\]+\/(?=Entity|ValueObject)(?:[^\\\\]+)?$/";
//EntityとValueObjectの2つを指定
$result = preg_match($pattern, $path);
var_dump((bool)$result); //true
複数以外を指定するときの正規表現
?!
と|
を併用
$path = "/app/packages/Domain/Sample/Entity.php";
//Entity
$pattern = "/^\/app\/packages\/Domain\/[^\\\\]+\/(?!Entity|ValueObject)(?:[^\\\\]+)?$/";
//EntityとValueObjectの2つを指定
$result = preg_match($pattern, $path);
var_dump((bool)$result); //true
$path = "/app/packages/Domain/Sample/ValueObject.php";
//ValueObject
$pattern = "/^\/app\/packages\/Domain\/[^\\\\]+\/(?!Entity|ValueObject)(?:[^\\\\]+)?$/";
//EntityとValueObjectの2つを指定
$result = preg_match($pattern, $path);
var_dump((bool)$result); //true
正規表現6
特定の文字を含むファイル名をしていするときの正規表現
//?=で肯定
$path = "/app/package/Domain/Sample/SampaleEntity.php";
$pattern = "/^\/app\/package\/Domain\/[^\\\\]+\/(?=.*Entity)(?:[^\\\\]+)?$/";
$result = preg_match($pattern, $path);
var_dump((bool)$result); //true
//?!で否定
$path = "/app/package/Domain/Sample/SampaleEntity.php";
$pattern = "/^\/app\/package\/Domain\/[^\\\\]+\/(?!.*Entity)(?:[^\\\\]+)?$/";
$result = preg_match($pattern, $path);
var_dump((bool)$result); //false
正規表現7
特定のディレクトリ全体を指定するときの正規表現
//?=で肯定
$path = "/app/app/Exceptions";
$pattern = "/^\/app\/[^\\\\]+\/(?=Exceptions).*$/";
$result = preg_match($pattern, $path);
var_dump((bool)$result); //true
$path = "/app/app/Exceptions";
$pattern = "/^\/app\/[^\\\\]+\/(?=Http).*$/";
$result = preg_match($pattern, $path);
var_dump((bool)$result); // false
//?!で否定
$path = "/app/app/Exceptions";
$pattern = "/^\/app\/[^\\\\]+\/(?!Exceptions).*$/";
$result = preg_match($pattern, $path);
var_dump((bool)$result); //false
$path = "/app/app/Exceptions";
$pattern = "/^\/app\/[^\\\\]+\/(?!Http).*$/";
$result = preg_match($pattern, $path);
var_dump((bool)$result); // true