FlexUnit4 での SequenceRunner を使ったテストをシンプルに書くためのユーティリティクラス/関数


SequeceRunner を使ったテストコードがごちゃごちゃしててテスト内容が読み辛かったので作ってみた。

以下のようなテストコードが

```actionscript:before
var sequence:SequenceRunner = new SequenceRunner( this );
// anyEvent を待つ
sequence.addStep( new SequenceWaiter( target, "anyEvent", 1000 ) );
// Target#hoge() を呼び出す
sequence.addStep( new SequenceCaller( target, function():void {
  target.hoge();
} ) );
sequence.addAssertHandler( function( evt:Event, obj:Object ):void {
  // target インスタンスの fuga() メソッドが呼び出されること
  assertThat( target, received().method( "fuga" ) );
} );
sequence.run();
```

以下のようにシンプルで見通しの良いコードになります。

```actionscript:after
sequence( this )
.steps(
  // anyEvent を待つ
  waitEvent( target, "anyEvent" ),
  // Target#hoge() を呼び出す
  call( function():void {
    target.hoge();
  } )
)
.assertion(
  // target インスタンスの fuga() メソッドが呼び出されること
  assertThat( target, received().method( "fuga" ) );
)
.run();
```

# コード

```actionscript:SimplifiedSequenceRunner.as
import flash.events.Event;
import flash.events.EventDispatcher;
import flash.events.IEventDispatcher;

import org.flexunit.asserts.fail;
import org.fluint.sequence.ISequenceStep;
import org.fluint.sequence.SequenceCaller;
import org.fluint.sequence.SequenceDelay;
import org.fluint.sequence.SequenceEventDispatcher;
import org.fluint.sequence.SequenceRunner;
import org.fluint.sequence.SequenceWaiter;

/**
 * FluentableSequenceRunner インスタンスを生成するユーティリティ関数
 */
function sequence( testCase:* ):SimplifiedSequenceRunner
{
	return new SimplifiedSequenceRunner( testCase );
}

/**
 * SequenceWaiter インスタンスを生成するユーティリティ関数
 */
function waitEvent( target:IEventDispatcher, eventName:String ):ISequenceStep
{
	return new SequenceWaiter( target, eventName, 3000, function( obj:Object ):void {
		fail( "Timeout Occurred before expected event (" + eventName + ")" );
	} );
}

/**
 * SequenceWaiter インスタンスを生成するユーティリティ関数
 */
function dispatchEvent( target:EventDispatcher, event:Event ):ISequenceStep
{
	return new SequenceEventDispatcher( target, event );
}

/**
 * SequenceDelay インスタンスを生成するユーティリティ関数
 */
function delay( milliSec:int ):ISequenceStep
{
	return new SequenceDelay( milliSec );
}

/**
 * SequenceCaller インスタンスを生成するユーティリティ関数
 */
function call( target:IEventDispatcher, procedure:Function ):ISequenceStep
{
	return new SequenceCaller( target, procedure );
}

/**
 * SequenceRunner を使用したテストを簡潔に記述するためのユーティリティクラス
 */
class SimplifiedSequenceRunner
{
	private var runner:SequenceRunner;
	
	/**
	 * コンストラクタ
	 */
	public function SimplifiedSequenceRunner( testCase:* )
	{
		runner = new SequenceRunner( testCase );
	}
	
	/**
	 * SequenceStep の追加
	 */
	public function steps( ...args ):SimplifiedSequenceRunner
	{
		for each ( var step:ISequenceStep in args )
			runner.addStep( step );
		return this;
	}
	
	/**
	 * AssertHandler の追加
	 */
	public function assertion( assertFunc:Function ):SimplifiedSequenceRunner
	{
		runner.addAssertHandler( function( evt:Event, obj:Object ):void {
			assertFunc();
		}, null );
		return this;
	}
	
	/**
	 * SequenceRunner の実行
	 */
	public function run():void
	{
		runner.run();
	}
}
```

# 使い方

上記コードを適当な場所に格納して当ユーティリティを使いたいテストクラスのasファイルの最後（ package 定義の外）で、以下のように include します。（include のパスは相対パスで記述する必要があるので注意）

```
package com.hoge.fuga {
   … テストクラスは省略 … 
}

include "../../includes/SimplifiedSequenceRunner.as";
```