nelmio/aliceでcurrentの値をintegerとして扱う方法について

ちょっと古いプロジェクトで、SymfonyのバージョンやPHPのバージョンを上げたいと思いましたがテストがないのでこわいなということで、テストを書き始めました。
nelmio/aliceを使ってテスト用のダミーデータを作っていましたが current まわりでちょっとつまずいてしまいました。
どのような問題が起きたのか?
コンストラクタに1から順に番号をもつ値が必要だったので current の値を使おうと考えていました。
以下のようなコンストラクタです。
public function __construct(private Map $map, private int $number, float $lat, float $lng)
{
$this->location = new LatLng($lng, $lat);
}
これに対してこのようなFixtureの定義をしました。
App\Entity\Map:
map1:
name: 'テスト'
aliasName: 'test1'
open: true
App\Entity\Shop:
distance{1..300}:
__construct: ['@map1', '<current()>', 35.684062887918, 139.77446354018]
この状態でFixtureをロードすると以下のようなエラーが発生します。
TypeError: Argument 2 passed to App\Entity\Shop::__construct() must be of the type int, string given, called in /app/vendor/nelmio/alice/src/Generator/Instantiator/Chainable/NoCallerMethodCallInstantiator.php on line 51
これは <current()> メソッドがstringの値を返してしまうので型が不一致になってエラーになっています。
キャストしてみる
aliceにはキャスト関数が用意されています。
https://github.com/nelmio/alice/blob/master/doc/customizing-data-generation.md#cast
<current()>のキャストしてしまえばいいのでは?と思ったので以下のようにFixtureの定義を修正しました。
App\Entity\Map:
map1:
name: 'テスト'
aliasName: 'test1'
open: true
App\Entity\Shop:
distance{1..300}:
__construct: ['@map1', '<intval(current())>', 35.684062887918, 139.77446354018]
実行してもaliceではエラーになりません。
ただしこれにも問題があって、必ず値が 0 になってしまいcurrentの値が使えるわけではないです。
どうやらaliceでは複数の関数を重ねる書き方がサポートされていないようです。
$currentをキャストする
そもそもaliceにはIdentityという機能(関数)が用意されていて、phpのコードをまぜて書くことができます。
<identity(1 * 2)> みたいなカタチでphpのコードを混ぜられます。
そしてidentityは省略可能で <()> と <identity()> は同じです。
https://github.com/nelmio/alice/blob/master/doc/customizing-data-generation.md#identity
つまり <(new \DateTime('2000-01-01'))> みたいに書くこともできちゃうわけです。
さらに、current() はidentityでは使用できませんが、identityの中で使う場合$current という変数として展開されています。
ドキュメントに書かれています。
The value current (result of <current()>) with the variable $current https://github.com/nelmio/alice/blob/master/doc/advanced-guide.md#identity
ここまでくれば $current をキャストしてしまえばいいわけです。
App\Entity\Map:
map1:
name: 'テスト'
aliasName: 'test1'
open: true
App\Entity\Shop:
distance{1..300}:
__construct: ['@map1', '<((int)$current)>', 35.684062887918, 139.77446354018]
まとめ
<current()>はstringで値を受け取ってしまう<((int)$current)>でintとして扱える
最後に
blueskyでポストして反応していろいろアドバイスをくれた @ttskchさんありがとうございます!!!