type holyshared = Engineer<mixed>

PHP、Hack、Ruby、OCaml、Javascript周りの技術ブログ

Hacklangのパッケージのテストコードを、型チェックかかるようにしたかったが断念した話

f:id:holyshared:20160305171858p:plain

タイトルの通りHacklang用のパッケージを開発していて、テストコードも型のチェックしたかったので、 できるか試してみました。

今、自分がパッケージ開発で使用しているテストツールは下記の通りです。

この構成だと、ソースはHackで書いて、テスト自体はPHPのエコシステムを使う感じになります。
これはこれでいいのですが、テストコードをpartialモードにする必要があり、テストコード内の型の矛盾などが、静的解析でチェックできない場合があります。

その場合、テストコードの型矛盾などの問題は、ランタイム時にようやく判明する可能性が高くなります。
極力そうゆうはことにはしたくないので、じゃあテストコードもstrictで書けばよくね?ってことになります。

Hacklangでテストコード書くには

基本的にテストコードをHackで書くには、次の方法があると思います。

  1. 既存のPHPのテスティングフレームワークを使用しつつ、テストコードをHackで書く
  2. Hacklang用のテスティングフレームワークを利用する

1の場合は既存のPHPテスティングフレームワークはそのままで、テストコードだけHackで書く方法です。
この場合、PHPのコードで、型の解決ができない部分がどうしてもでてきます。
じゃあその部分はどうするかというと、型の定義ファイルを作成して補います。

Hackのモードでdeclモードというものがあって、クラスや関数のシグニチャをファイルに書くと、型チェックの際に定義ファイルを参考に型のチェックを行ってくれます。
これでテストコードも型のチェックの恩恵を受けれるようになります。

2の場合は、そのままんまの意味で、HackUnitなどのHack用のテスティングフレームワークを利用します。

この場合、素直にHackでテストコード書けばいいので手間がかかならいです。

型の定義ファイル書くのだるいので、HackUnitで

自分は型の定義ファイル書きたくなかったので、HackUnitでテストコード書くことにしました。
機能が少なくて、学習コストはそんな高くなくさくっと導入できました。
ただ、型のチェックまだごまかしてるところが若干あります。

リリース後に気づいた問題

無事テストコードもHackで書けたのでリリースしまして、利用しているパッケージの方のバージョンあげようと思い、composer update実行し、型のチェックをかけたら、テストコードで型エラーがでるようになりました。

Unbound name: HackPack\HackUnit\Contract\Assert (an object type)

HackUnitのクラス名が解決できてないようで、なんでかなと思ったら、基本的に依存してるパッケージの開発用に使用するパッケージはインストールされないのを忘れていました

下のような場合、依存しているパッケージsome_packageのrequire-devで指定されているパッケージはインストールされないので、型のチェックが通りません。

.hhconfig
src
vendor
    /some_package < このパッケージのテストコードが型チェックに引っかかる。

なので、パッケージ開発している時はいいのですが、作ったパッケージを利用したさらに別のパッケージ作る場合は注意が必要です。 基本的に型をチェックをかけたくないコードのフィルタリングがhh_clientできないので、完全に詰んでる状態です。

flowtypeとかは、設定ファイルでその辺をコントロールできるのですが、何でhh_clientとはできないないのか謎ですね。

結果どうしたか

revertして、元に戻しました。
いまさら、revertして戻したくないなーと思ったのですが、いい解決方法がなかったので….
composerの設定でテストコードを除外して配布見たいなのができればいいのですが、できそうになかったし…