Starling な環境で FlexUnit Test を実行する

まえがき
-------------------

最近 AIR for iOS, AIR for Android を使った事例をよく聞きます。
で、それらに向けたアプリをヌルヌルした動きにしようと思ったら
当然グラフィカルな処理を GPU に依存するようなライブラリがメインとなることでしょう。

2D 用の GPU サポートなライブラリとしては Starling が最も良く怖いいんたーねっつ上で耳にします。

ゲームなどの開発となると、当然グラフィカルなコンポーネントやゲームロジック部分以外にも
大事な要素としてサーバーとのつなぎ込みやローカルなStorageへの保存なども含まれてきます。

その縁の下の力持ち的な領域から、モデルの変更だとかサーバーからの push だとかを
イベントを使って通知しようと思った場合
今までの `flash.events.Event` や `flash.events.EventDispatcher` ではなく、
`starling.events.Event` や `starling.events.EventDispatcher` を採用したほうが
グラフィカルな部分を担当している方達の負担が減ると思われます。

で、当然コアなロジックを担当する以上、
感覚としてはサーバーサイドと同じようなので
テスト書かないとか生ぬるいことを言うわけには行きません。

グラフィカル、インタラクティブな領域は思うところが色々あるので目をつむりますが
テスト書けるところは書こうぜというスタンスが近年モヒカンからのマサカリ防壁として役に立つような印象を持っています。
いや、日本古来より伝わる言い方をすると転ばぬ先の杖というやつだったり
石橋を叩いて渡るだとかそういうアレです。

といっても僕もテストジャンキーではないですし、
当然モヒカンなどではありません。
モヒカンにする髪がないのは僕と関わりのある方であればご承知いただけるかと思います。

とりあえず、Starling 環境だろうとそんなの関係なく
ナチュラルにテスト書き始めるよねという話です。

本題
---------------

さて、まえがきが長くなりましたが本題に。
FlexUnit テストって何よ、どう書くのよはっきりしなさいよ！という方は以下がわかりやすいので
ご覧いただければど。

> [[FlexUnit] 〜テストの拳〜 世紀末終わったけど、Flashまだ終わってないし、あべし言いたくないし、FlexUnitでテストする？](http://katapad.com/wp/2013/04/23/abeshi/)


で、サーバーにリクエストしてそのレスポンスをちゃんとパースで来てるかとか言うテストがしたい時
非同期なテストの書き方は以下のようになります。

```as3
package test.project.starlingTestShitai
{
	import flash.events.Event;
	
	import org.flexunit.async.Async;

	import starling.events.EventDispatcher;
	

	public class TestUserSendInviteAPIJob
	{
		private var _starlingEventDispatcher継承した者:starling.events.EventDispatcher;
		
		
		[Before]
		public function setUp():void
		{
			_starlingEventDispatcher継承した者 = new starling.events.EventDispatcher();
		}
		
		[After]
		public function tearDown():void
		{
		}
		
		[BeforeClass]
		public static function setUpBeforeClass():void
		{
			trace("▂▅▇█▓▒░('ω')░▒▓█▇▅▂うわあああああああ");
		}
		
		[AfterClass]
		public static function tearDownAfterClass():void
		{
		}
		
		
		[Test(async, description="ひどうきなてすとがしたい", timeout="1000")]
		public function shouldSendAPI():void
		{
			_starlingEventDispatcher継承した者.addEventListener( Async.asyncHandler( this, _successHandler, 1000));
			//ここで問い合わせるとかね
			_starlingEventDispatcher継承した者.execute();
		}
		
		/**
		 * 普通に starling のイベントを受け取る
		 */
		private function _successHandler( event:starling.events.Event, ctx:Object ):void
		{
			trace( "called" );
			//あとはパースの結果とかをテストする
		}
		
	}
}
```

これを実行するとオメーのイベント `flash.events.Event` に変換できねぇよヒャッハー！
と地獄の底からエラーが沸き上がってきます。
これ FlashBuilder だとマジで地獄の底から湧き上がってるんじゃねぇかと思うくらい特定しづらいです。

実際のところ犯人は FlexUnit の中にいる、`AsyncHandler` タソです。
この子が普通に `flash.events.EventDispacther` 生まれな子で `flash.events.Event` を待ち構えているので
エラーが起きるわけですね。

え、これどうすればいいの詰んでるじゃんと
プロジェクトの切羽詰まった状況の中だと大慌てするわけですが
以下のようにアダプターというか代理人を1個立ててやれば何とかなりそうです。

```as3
package test.project.starlingTestShitai
{
	import flash.events.Event;
	
	import org.flexunit.async.Async;

	import starling.events.EventDispatcher;
	

	public class TestUserSendInviteAPIJob
	{
		private var _starlingEventDispatcher:starling.events.EventDispatcher;
		private var _adapter:flash.display.Sprite;
		
		[Before]
		public function setUp():void
		{
			_adapter = new flash.display.Sprite();
			_starlingEventDispatcher = new starling.events.EventDispatcher();
		}
		
		[After]
		public function tearDown():void
		{
		}
		
		[BeforeClass]
		public static function setUpBeforeClass():void
		{
			trace("▂▅▇█▓▒░('ω')░▒▓█▇▅▂うわあああああああ");
		}
		
		[AfterClass]
		public static function tearDownAfterClass():void
		{
		}
		
		
		[Test(async, description="ひどうきなてすとがしたい", timeout="1000")]
		public function shouldSendAPI():void
		{
			_adapter.addEventListener( Event.COMPLETE, Async.asyncHandler( this, _calledHandler, 1000))
			_starlingEventDispatcher.addEventListener( starling.events.Event, _successHandler);
			_starlingEventDispatcher.execute();
		}
		
		/**
		 * 普通に starling のイベントを受け取る
		 */
		private function _successHandler( event:starling.events.Event ):void
		{
			trace( "called" );
			//ここで flash.events.Event をよんであげる
			_adapter.dispatchEvent( new Event( Event.COMPLETE ));
		}
		
		/**
		 * これで非同期なイベントコールバックが呼ばれたかどうかのテスト代わりになる
		 */
		private function _calledHandler( event:flash.events.Event, , ctx:Object ):void
		{
			trace("hey");
		}
	}
}
```

これで多分テストを書き続けられると思います。
まぁ実際コードにしてみるとこんなんわざわざ記事にしてんじゃねーよというレベルですね。
はい。

当然、この情報は flexunit 側が Starling とかに対応した瞬間にゴミになるので
皆さんバージョンには気をつけてくださいね。

flexunit にもそもそも与えたハンドラが呼ばれたかどうかみたいなテスト項目があるともっと捗るなと思っている今日このごろなのですがだれかご存知でしたら教えて下さい。

あと flexunit そんなにわかってないのでそうじゃねーよというツッコミもお待ちしています。
今日はもう寝ます。

それでは。