Index: /as3/Syndication/trunk/tests/xml/cellfusion-atom.xml =================================================================== --- /as3/Syndication/trunk/tests/xml/cellfusion-atom.xml (リビジョン 952) +++ /as3/Syndication/trunk/tests/xml/cellfusion-atom.xml (リビジョン 952) @@ -0,0 +1,945 @@ + + + cellfusion blog + + + tag:blog.cellfusion.jp,2008-02-25://2 + 2008-08-10T12:18:30Z + + Movable Type 4.1 + + + 今さら「はて☆スタ」つけた + + tag:blog.cellfusion.jp,2008://2.634 + + 2008-08-10T12:13:41Z + 2008-08-10T12:18:30Z + + 記事に対しての反応とかを見たかったから、今さらだけど はてなスター つけてみた。... + + Mk-10:cellfusion + http://www.cellfusion.jp/ + + + + + + + 記事に対しての反応とかを見たかったから、今さらだけど はてなスター つけてみた。

]]> + +
+
+ + + DisplayObject.transform.matrix + + tag:blog.cellfusion.jp,2008://2.633 + + 2008-08-07T09:43:18Z + 2008-08-07T11:00:44Z + + いままで Sprite でズーム表現をするためには、Flash で下記のように基... + + Mk-10:cellfusion + http://www.cellfusion.jp/ + + + + + + + + いままで Sprite でズーム表現をするためには、Flash で下記のように基準点を中心に持ってくるか、Sprite を入れ子にするという方法を使ってたんだけど。

+ +

基準点を設定

+ +

それってどうしても一手間かかるし、何よりも基準点を移動させると AS で弄るときに座標系が混乱してくるのでどうにか方法はないのかなと探っていたら DisplayObject.transform.matrix を使うと左上が基準点でもオブジェクトの真ん中を基準として動かす事ができた!

+ +

コードは下記の通り

+ + + +
package  
+{
+	import flash.display.Sprite;
+	import flash.geom.Matrix;
+	import flash.geom.Transform;	
+	
+	public class TransformTest extends Sprite 
+	{
+		private var _sp:Sprite;
+		
+		public function TransformTest()
+		{
+			_sp = new Sprite();
+			_sp.x = 150;
+			_sp.y = 150;
+			
+			// 四角形を作る
+			_sp.graphics.beginFill(0x000000);
+			_sp.graphics.drawRect(0, 0, 100, 100);
+			_sp.graphics.endFill();
+			
+			// 基準点をわかりやすくするために左上に赤い矩形を作る
+			_sp.graphics.beginFill(0xFF0000);
+			_sp.graphics.drawRect(0, 0, 5, 5);
+			_sp.graphics.endFill();
+			
+			// 変換用の Matrix を準備
+			var mat:Matrix = new Matrix();
+			
+			// 回転の中心点を変えるために -50 する
+			mat.translate(-50, -50);
+			
+			// 回転する
+			mat.rotate(45*Math.PI/180);
+			
+			// 元の位置に戻す
+			mat.translate(50, 50);
+			
+			// 現在表示している matrix と合体させる
+			mat.concat(_sp.transform.matrix);
+			
+			trace("before:"+_sp.transform.matrix);
+			
+			// 中心点で回転させるための Matrix を反映する
+			_sp.transform.matrix = mat;
+			
+			trace("after:"+_sp.transform.matrix);
+			trace("rotation:"+_sp.rotation);
+			
+			addChild(_sp);
+		}
+	}
+}
+ + + +

特殊なのが

+ +
_sp.transform.matrix = mat;
+ +

の部分。直接いじれないので、別に Matrix を作成して合成して反映している。ココ以外は Matrix の使い方を知っていればそのままの知識が使える。

+ +

DisplayObject.transform.matrix を使う事で Sprite 関係は基本的に左上を基準点として作成すれば座標系で混乱する事もなるし、今まで以上にアニメーションの幅も広がるよね。

+ +

ちょっと上のコードだと動いてるのかわかりにくいので、enterFrame でくるくる回してみた。

+ + + +
package  
+{
+	import flash.display.Sprite;
+	import flash.events.Event;
+	import flash.geom.Matrix;	
+	
+	public class TransformEnterFrame extends Sprite 
+	{
+		private var _sp:Sprite;
+
+		public function TransformEnterFrame()
+		{
+			_sp = new Sprite();
+			_sp.x = 150;
+			_sp.y = 150;
+			
+			// 四角形を作る
+			_sp.graphics.beginFill(0x000000);
+			_sp.graphics.drawRect(0, 0, 100, 100);
+			_sp.graphics.endFill();
+			
+			// 基準点をわかりやすくするために左上に赤い矩形を作る
+			_sp.graphics.beginFill(0xFF0000);
+			_sp.graphics.drawRect(0, 0, 5, 5);
+			_sp.graphics.endFill();
+			
+			addEventListener(Event.ENTER_FRAME,	enterframeHandler);
+			
+			addChild(_sp);
+		}
+		
+		private function enterframeHandler(event:Event):void
+		{
+			var mat:Matrix = new Matrix();
+			mat.translate(-50, -50);
+			
+			// 5°ずつ回転させる
+			mat.rotate(5*Math.PI/180);
+			
+			mat.translate(50, 50);
+			mat.concat(_sp.transform.matrix);
+			_sp.transform.matrix = mat;
+			
+			// 座標がどうなっているのか trace
+//			trace("x:"+_sp.x, "y:"+_sp.y);
+		}
+	}
+}
+ + + +

これでオブジェクトの基準点じゃなくて、中心で回ってるのがよくわかると思う。

+ +

transform.matrix は Flash8 くらいからあるので、AS2.0 を使っている人でも同じ使い方で使用できると思う。

+ +

今回の サンプルファイル

+ +

他には fl.motion.MatrixTransformer とか使ってもできそうな感じ。後でこいつも触ってみよう。

+ +

Tweener でこのプロパティを使いたい場合は fladdict さんの MatrixShortcut.as を使うといいよ!
+fladdict» ブログアーカイブ » Tweener拡張で、MovieClipをMatrixで超変形をできるようにした

]]> + +
+
+ + + Flash IDE のヘルプをブラウザで見る方法 + + tag:blog.cellfusion.jp,2008://2.632 + + 2008-08-06T02:16:36Z + 2008-08-06T02:49:50Z + + 今まで気づいてなかったのもだいぶ問題ありなんですが、Flash IDE のヘルプ... + + Mk-10:cellfusion + http://www.cellfusion.jp/ + + + + + + + + + + + 今まで気づいてなかったのもだいぶ問題ありなんですが、Flash IDE のヘルプは HTML なのでブラウザでも見れるよ!
+OSX だと下記のディレクトリに格納されてるみたい。

+ + + +
file:///Library/Application%20Support/Adobe/Flash%20CS3/ja/Configuration/HelpPanel/Help
+ + + +

AS3 とか AS2 とか個別に格納されてるので、IDE の検索がいまいちだと思ってるならココを検索対象にして検索するといいんじゃないかな?

+ +

HTML の場所の調べかたは

+ + +
    +
  1. Flash IDE のヘルプを適当に開く
  2. +
  3. 中のリンク部分を右クリック
  4. +
  5. 「リンクをコピー」って言うコンテキストメニューをクリック
  6. +
  7. コピーしたリンクをブラウザで開けばOK!
  8. +
+ + + +

こうすれば、いちいちググってた人もローカルでさくさく作業ができるね!
+あ、でも Flash の IDE をインストールしてる人だけだよ。

+ +

さらに livedocs.adobe.com のリンクをローカルに書き換えてくれるグリモンがあれば完璧?
+そこはエロイ人に任せた!

]]> + +
+
+ + + AS でカレンダーみたいな表示するよ! + + tag:blog.cellfusion.jp,2008://2.631 + + 2008-07-31T09:25:28Z + 2008-08-07T11:02:30Z + + ikacr4u @cellfusion にっ日本語でおk!(  今日中に作れとか... + + Mk-10:cellfusion + http://www.cellfusion.jp/ + + + + + + + ikacr4u @cellfusion にっ日本語でおk!(  今日中に作れとか言われてバカ言ってんじゃねーよって感じです。ソース落ちてないしもうめんどい。(

+ +

と ikacr4u が寂しい事言ってたのを ASer としては見過ごせないので、簡単な AS サンプル作っちゃうよ!

+ +

hoge という識別子が着いた MovieClip の中には tf という TextField がある想定だよ!
+とりあえず、今月のカレンダーを作成する方法。

+ + + +
// 何も引数をつけないと今現在の日付が入ったDateができる
+var date:Date = new Date();
+// 月の初めの日付にする
+date.setDate(1);
+// 月の初めの曜日を取得
+var day:Number = date.getDay();
+
+// 日付分を for で回す(めんどくさいので31固定)
+for (var i:Number = 0; i < 31; i++) {
+  var num:Number = i + day;
+  // x の値を求めるために、 7 で割ったあまりを xpos に入れる
+  var xpos:Number = num % 7;
+  // y の値を求めるために 7 で割って切り下げする
+  var ypos:Number = Math.floor(num / 7);
+  
+  // MovieClip を作成
+  var mc:MovieClip = attachMovie("hoge", "hoge"+i, i);
+  // 作成した MovieClip の x 値を xpos を参考に設定
+  mc._x = xpos * 40;
+  // y 値を ypos を参考に設定
+  mc._y = ypos * 30;
+
+  mc.tf.text = i;
+}
+ + + +

サンプル as_calendar.fla

+ +

とりあえず、簡単に説明してみた。
+図とか入れた方がわかりやすそうなので、あとで更新するよ。

]]> + +
+
+ + + DS-10 届いてた! + + tag:blog.cellfusion.jp,2008://2.629 + + 2008-07-28T00:58:28Z + 2008-07-28T01:16:37Z + + メール便だったのでおそらく土曜日には着いていたっぽい、会社のポストに突き刺さって... + + Mk-10:cellfusion + http://www.cellfusion.jp/ + + + + + + + + + メール便だったのでおそらく土曜日には着いていたっぽい、会社のポストに突き刺さってました・・・。

+ +

届いてたDS-10

+ +

早速、Demo-1 を流しながら KAOSSPAD とかで遊んでみたけど、これ楽しすぎるなぁ。初めてのシンセサイザーなのでこれからじっくり触ってみる!

]]> + +
+
+ + + ようやく再始動 + + tag:cellfusion.s49.coreserver.jp,2008:/blog//2.627 + + 2008-07-27T11:06:05Z + 2008-07-27T11:12:56Z + + Twitter に慣れすぎてなかなか blog に戻ってこれなかったけど、今日か... + + Mk-10:cellfusion + http://www.cellfusion.jp/ + + + + + + + Twitter に慣れすぎてなかなか blog に戻ってこれなかったけど、今日から少しずつ再始動していくよ!
+というわけで、ようやくデフォルトのテンプレートから変更しました。といってもだいぶ突貫なので Mac でしか確認してなかったりするので、うまく見えてない方はごめんなさい・・・。徐々にいじっていきます!
+上の検索部分も作り方が悪かったのかうまく動いていなかったり・・・、後で直すから今は勘弁してー!

+ +

あと、今まで permalink が日付と番号という訳のわからない組み合わせになっていたんですが、これからは「記事ID」にしたので基本変わることはないと思います・・・・たぶん。
+なぜか ID が 300 とかから始まってるんですが・・・。

]]> + +
+
+ + + サーバーばっかりさわってるな + + tag:cellfusion.s49.coreserver.jp,2008:/blog//2.625 + + 2008-07-26T04:40:14Z + 2008-07-27T10:33:40Z + + ちょっと前に TIG を入れてからずっとサーバーとかいじってるよ! 最近は mo... + + Mk-10:cellfusion + http://www.cellfusion.jp/ + + + + + + + ちょっと前に TIG を入れてからずっとサーバーとかいじってるよ!

+ +

最近は mobirc を make するために CPAN からライブラリを落としてきたり、足りないものがあったら apt-get したり・・・いろいろやってるうちにちょっとずつ詳しくなってきている気がする。
+正直、仕事でサーバーとかいじってる人は尊敬する。

+ +

そんなわけで、昨日は Plagger いれたり FFmpeg 入れたりしました。
+特に何かするわけじゃないんですが、サーバーいじりが楽しいです。

+ +

mobirc は config.yaml がよくわからなくてまだ動いてないですけど・・・。

+ +

もうちょっとしたら、先週のアニメイトオフ(別名:@holynight のメイド女装オフ)のエントリーでもするかなー。

]]> + +
+
+ + + TIG が動くようになった! + + tag:cellfusion.s49.coreserver.jp,2008:/blog//2.624 + + 2008-07-20T04:43:20Z + 2008-07-27T10:33:40Z + + 苦節数ヶ月・・・ようやく TIG がまともに動くようになったよ! @shunir... + + Mk-10:cellfusion + http://www.cellfusion.jp/ + + + + + 苦節数ヶ月・・・ようやく TIG がまともに動くようになったよ!

+ +

@shunirr が TIG を活用しているのを見て、自分も使いたいと思って鯖にインストールしたけど、ログがうまくとれなくて今まで放置してた。
+けど、さっきようやくログがとれるようになったよ!

+ +

忘れないようにメモっておく。

]]> + まず TIG のオプションで --enable-trace で動作を確認できるようにしてしばらくログとにらめっこ。

+ +

最初のログは取得できてるんだけど、更新がうまくいってない・・・。
+ログを取得する部分がおかしいみたい。

+ +

ログを取得する URL をブラウザで表示したら since オプションを使っていて、時間指定が GMT なのに9時間進んでいた・・・。

+ +

鯖の時間の設定がおかしかったので下記を参考にして ntp をインストールして時間設定をなおした。

+ +

時刻の設定 - intrinsic feeling

+ +

もう一度、挑戦したら今度はきちんと表示された。
+なんかすごく初歩的なところでつまずいてた・・・。

+ +

アイコンが表示されないのは寂しいけど、結構便利だなー。
+あと tiarra と mobirc を追加してモバイル用の環境を構築予定。

+ +

ちなみに Twitter API は下記のサイトで翻訳されてるので気になる人は読んでみるといいよ。

+ +

[観] Twitter API 仕様書

]]> +
+
+ + + バイクがおかしくなった + + tag:cellfusion.s49.coreserver.jp,2008:/blog//2.623 + + 2008-06-22T11:02:55Z + 2008-07-27T10:33:40Z + + バイクがおかしくなってはじめてメンテナンスの偉大さに気付く駄目ライダーなのです。... + + Mk-10:cellfusion + http://www.cellfusion.jp/ + + + + + + + + + + バイクがおかしくなってはじめてメンテナンスの偉大さに気付く駄目ライダーなのです。
+ちょっと前からアクセルを思いっきり開けると回転数が落ちてストールするようになってたのですが(その時点でバイク屋に持って行けば良かったんですよね・・・)、引っ越しとかと重なって結局そのまま乗ってたらエンジンすらかかりにくくなってしまいましたーorz

+ +

今頃あわててもしょうがないけど、取りあえず自分で直せそうなところはやってみようと土日を使ってメンテナンスしました(写真撮っておけば良かった)。

+ +

やったことはこんな感じ。
+全く知識がないので本とか、ググったりしながら作業。

+ + +
    +
  • エンジンオイル交換(ついでにフィルター交換)
  • +
  • スパークプラグ交換
  • +
  • エアクリーナー交換
  • +
+ + + +

どうせ触るならと思ってエンジンオイルとかも交換しつつ、色々やってみたけど特に変わらず・・・。
+エンジンはかかるけど、思いっきり開けるとやっぱり駄目だった。

+ +

どうやら、キャブとかが怪しいらしい・・・そのへんは今の自分では触れなさそうなので、明日近所のバイク屋さんに持って行くことにするー。
+金額がアレだったら、頑張って自力でするしかないなー。

+ +

だがそれより先に、明日からの出勤をどうするかが問題だ!

]]> + +
+
+ + + Flash Switcher入れてみた(OSX版) + + tag:cellfusion.s49.coreserver.jp,2008:/blog//2.622 + + 2008-05-21T16:56:58Z + 2008-07-27T10:33:40Z + + Firefox 3.0 RC 1 がリリースされたのでついでにインストールしてみ... + + Mk-10:cellfusion + http://www.cellfusion.jp/ + + + + + + + + + Firefox 3.0 RC 1 がリリースされたのでついでにインストールしてみた。

+ +

まず、「 Flash Switcher って何?」っていう人に説明。
+Flash Switcher っていうのは、ブラウザに入っている Flash Player をいちいちインストールしなくても手軽に変更できる Firefox の便利プラグインです。

+ +

普通にインストールするだけだとうまくいかなかったので作業手順をメモ。
+ついでに、簡単な操作方法も書いておく。

]]> + +
  • まずは Firefox 3.x をインストール
  • +
  • 続いて Flash Switcher をインストール
    +再起動後右下にアイコンが出現
    +
  • + + + + +

    Flash 9.0 r124 と Flash 9.0 r115 がデフォルトで入っているので早速試してみても、再起動後エラーダイアログが出て成功しません。
    +とここで悩んでたところ Saqoosha 先生がいろいろ教えてくれた。

    + +

    @cellfusion /Library/Internet Plug-Ins のパミッションを 777 にしてみ

    + +

    Firefox を終了してパーミッションを変更後、試してみても同じエラーが出て駄目だった。

    + +

    @cellfusion んじゃあ、Fx 終了して Flash Player.plugin と flashplayer.xpt 削除してもっかいとらい。

    + +

    flashplayer10が入ってる環境だと flashplayer.xpt が入ってないかもしれないけど、この二つを削除して起動したらばっちりうまくいきました!
    +うまくいかない人は Saqoosha 先生の助言の通りにやってみるといいかも。

    + +

    簡単な操作説明

    + +

    Switch 出来る Flash Player の増やし方

    + + +
      +
    1. まずは増やしたい Flash Player を普通にインストールします。
    2. +
    3. インストール完了後、Firefox を起動して Flash Switcher アイコンをクリック、下記のダイアログが出てきます。
      +
    4. +
    5. 一番上の Flash Player をクリックすると、保存するか削除するかのダイアログが出てくるので「Save as...」を選択して保存します。
    6. +
    7. 保存するときに Player の名前をつけられるのでデフォルトのまま OK をクリックで完了です。
    8. +
    9. 再起動後リストに追加されます。
    10. +
    + + + +

    Flash Player を変更する

    + + +
      +
    1. Flash Switcher アイコンをクリック
    2. +
    3. 保存してある Flash Player の中から Switch したいプレイヤーをクリック。
    4. +
    5. Firefox が再起動後、新しい Player に Switch しています。
    6. +
    + + + +

    こんな感じで使えます。
    +Saqoosha さん、ありがとうございましたー!

    ]]> +
    +
    + + + そろそろターニングポイントな気がする + + tag:cellfusion.s49.coreserver.jp,2008:/blog//2.621 + + 2008-04-25T02:54:00Z + 2008-07-27T10:33:40Z + + 気がついたら3ヶ月以上放置してましたね。 最近はほとんど Twitter にいる... + + Mk-10:cellfusion + http://www.cellfusion.jp/ + + + + + + + 気がついたら3ヶ月以上放置してましたね。
    +最近はほとんど Twitter にいるのでついつい Blog を置き去りにしすぎました。

    + +

    ここんところゆるやかにだけど少しずつ周りの環境に変化があって、自分もそろそろ受けな行動は終わりにしてもっと攻めな行動を行おうかなと、気がついたら今年で25歳だしもうそろそろターニングポイントな気がする。

    + +

    東京とか別の土地に行きたいからそろそろ動き出さないとな。

    ]]> + +
    +
    + + + SocketURLLoader + + tag:cellfusion.s49.coreserver.jp,2008:/blog//2.619 + + 2008-01-21T04:44:36Z + 2008-07-27T10:33:40Z + + URLLoader だと RequestHeader とかうまくつけられなかった... + + Mk-10:cellfusion + http://www.cellfusion.jp/ + + + + + + + + + + URLLoader だと RequestHeader とかうまくつけられなかったので OZACC.blog: URLLoaderで紹介されてた。 +as3httpclient を Downloads から落としてきて使ってたつもりが、何度試してもうまくいかないので何故かと思っていたら、SVN と Downloads の中がまるっきり別物でした・・・orz

    + +

    Downloads に含まれているのは HTTPURLLoader っていうクラスでなんだか中途半端な状態なので、POSTとかでクエリが渡せません。 +ちゃんと SVN から落としましょー。ということでメモ。

    + +
    svn checkout http://as3httpclient.googlecode.com/svn/trunk/
    +
    +]]> + + +
    +
    + + + サーバーで保存したSharedObjectはローカルでも参照できるよ + + tag:cellfusion.s49.coreserver.jp,2008:/blog//2.617 + + 2008-01-05T09:24:40Z + 2008-07-27T10:33:40Z + + すいません、これ自分の操作ミスでローカルでも参照できると勘違いしてただけです。実... + + Mk-10:cellfusion + http://www.cellfusion.jp/ + + + + + + + + + + すいません、これ自分の操作ミスでローカルでも参照できると勘違いしてただけです。
    実際はドメインごとにSharedObjectが保存されているので、とれないとのことです。

    +

    ドキュメントにもさりげなく書かれていた・・・ドキュメントは一度目を通す癖をつけなくちゃ

    + +

    ブラウザの Cokkie のようなFlashのSharedObjectは保存したURLでしか参照できないような感じがするけど、設定次第ではローカルのswfからでも参照できるよ!

    + +

    たとえば、こんな風な使い方もできる。 +

      +
    1. サイト上でスクリーンセーバーの設定をする
    2. +
    3. SharedObjectに保存
    4. +
    5. スクリーンセーバーのswfからSharedObjectにアクセス
    6. +
    +うまく使えば、おもしろいことができそう。

    ]]> + + +

    ヘルプを見るとわかるけど、getLocal には3つの引数が用意されている。

    + +
    getLocal(name, [localPath], [secure]);
    + +

    通常 getLocal は getLocal("hoge"); のように名前だけ指定している場合が多いと思う。
    +それだと localPath に現在開いている絶対URLが保存されるため、そのURL以外からでは、保存した SharedObject にアクセスできなくなってしまう。
    +また、保存されたSharedObjectは開いているURLと関連してくるため、getLocal("hoge", "http://www.cellfusion.jp/"); と保存すると URL にこの文字列がないと参照できない。
    +つまり、ローカルでも参照できるようにするためにはlocalPathに "/" を指定してしまえば大丈夫!
    +ただ、この方法で保存したSharedObjectは名前さえわかってしまえば、他のサイトでも使用できてしまうので、絶対にかぶらない名前をつけることをオススメします。

    + +

    SharedObjectを保存するAS

    +
    +var mySO:SharedObject = SharedObject.getLocal("hoge", "/");
    +
    +// ない場合は新しく作る
    +if (mySO.data.profile == undefined) {
    +	trace("新しく作る");
    +	
    +	var temp:Object = new Object();
    +	
    +	temp.name = "cellfusion";
    +	temp.message = "スイーツ(笑)より ActionScript";
    +	
    +	mySO.data.profile = temp;
    +	mySO.flush(100);
    +} else {
    +	trace("すでにある");
    +}
    +
    +// 保存されているデータを出力
    +for (var idx:String in mySO.data) {
    +	trace(idx+":"+mySO.data[idx]);
    +}
    +
    + +

    先ほどで保存したSharedObjectを取得するAS

    +
    +var mySO:SharedObject = SharedObject.getLocal("hoge", "/");
    +
    +if (mySO.data.profile == undefined) {
    +	trace("保存されていない");
    +} else {
    +	trace("保存されている");
    +}
    +
    +// 保存されているデータを出力
    +for (var idx:String in mySO.data) {
    +	trace(idx+":"+mySO.data[idx]);
    +}
    +
    ]]> +
    +
    + + + mqoフォーマットをmodoでも読み込めるスクリプト書いた + + tag:cellfusion.s49.coreserver.jp,2007:/blog//2.615 + + 2007-12-08T12:25:44Z + 2008-07-27T10:33:40Z + + まだ、Mterialとかいろいろできてないんだけど、取りあえずVertexとPo... + + Mk-10:cellfusion + http://www.cellfusion.jp/ + + + + + + + + + + + + まだ、Mterialとかいろいろできてないんだけど、取りあえずVertexとPolyをインポートできるようになったので公開しておく。
    +スクリプトは勉強がてらに Python で書いてみたよ。

    ]]> + + +

    ソースコード

    +
    +    # python
    +    
    +    import sys
    +    import lx
    +    import re
    +    import string
    +    
    +    chunks = []
    +    materials = []
    +    objects = []
    +    scene = {}
    +    lines = []
    +    
    +    currentLayer = {}
    +    fileName = {}
    +    
    +    def parseChunk():
    +        chunkPrefix = re.compile('(Material|Object|vertex|face|Scene) (\"?.*\"?) {')
    +        
    +        state = ""
    +        
    +        for x in range(len(lines)):
    +            r = chunkPrefix.search(lines[x])
    +            if r != None:
    +                if r.group(1) == "Object":
    +                    objects.append({'name':r.group(2)})
    +                #elif r.group(1) == "Material": 
    +                    #materials.append({''})
    +                elif r.group(1) == "vertex":
    +                    objects[len(objects)-1]['vertex'] = []
    +                elif r.group(1) == "face":
    +                    objects[len(objects)-1]['face'] = []
    +                state = r.group(1)
    +            elif re.compile('}').search(lines[x]):
    +                state = ""
    +            else:
    +                if state == "Object":
    +                    arr = lines[x].split()
    +                    temp = []
    +                    for i in range(1, len(arr)):
    +                        temp.append(arr[i])
    +                        objects[len(objects)-1][arr[0]] = temp
    +                elif state == "vertex":
    +                    objects[len(objects)-1]['vertex'].append(lines[x].split())
    +                elif state == "face":
    +                    v = getParam(lines[x], 'V')
    +                    m = getParam(lines[x], 'M')
    +                    uv = getParam(lines[x], 'UV')
    +                    
    +                    temp = {}
    +                    if v != None:
    +                        temp['vertex'] = v
    +                    if m != None:
    +                        temp['material'] = m
    +                    if uv != None:
    +                        temp['uv'] = uv
    +                    
    +                    objects[len(objects)-1]['face'].append(temp)
    +                elif state == "Material":
    +                    print "Material"
    +                elif state == "Scene":
    +                    arr = lines[x].split()
    +                    temp = []
    +                    for i in range(1, len(arr)):
    +                        temp.append(arr[i])
    +                        scene[arr[0]] = temp
    +
    +        for i in range(len(objects)):
    +            currentLayer = lx.command("layer.newItem", type="mesh", name=objects[i]['name'])
    +            
    +            for vertex in objects[i]['vertex']:
    +                makeVertex(vertex)
    +            
    +            for face in objects[i]['face']:
    +                makeFace(face['vertex'])
    +        
    +    # Vertex を作成する
    +    def makeVertex(arr):
    +        lx.command("vert.new", x=arr[0], y=arr[1], z=arr[2])
    +    
    +    # Poly を作成する
    +    def makeFace(arr):
    +        current=lx.eval("query layerservice layers ? main")
    +    
    +        lx.command("select.element", layer=current, type="vertex", mode="set", index=arr[0])
    +        for i in range(1, len(arr)):
    +            lx.command("select.element", layer=current, type="vertex", mode="add", index=arr[i])
    +        
    +        lx.command("poly.make", type="face")
    +    
    +    # line 内で paramName(...)という形式で指定されているパラメーターを返します。
    +    def getParam(line, paramName):
    +        prefix = re.compile(paramName+"\((.*?)\)")
    +        
    +        temp = prefix.search(line)
    +        if temp == None:
    +            return None
    +	
    +        return temp.group(1).split()
    +    
    +    lx.eval('dialog.setup fileOpen');
    +    lx.eval('dialog.title "Import Metaseqoia file"');
    +    lx.eval('dialog.result "*.mqo"')
    +
    +    try :
    +        lx.eval('dialog.open')
    +        fileName = lx.eval('dialog.result ?')
    +        
    +        fp = open(fileName, "rb")
    +        data = fp.read()
    +        
    +        lines = data.split("\r\n")
    +
    +        parseChunk()
    +        
    +        fp.close()
    +    except IOError:
    +        lx.out(sys.exc_info()[0])
    +        lx.eval('dialog.setup error')
    +        lx.eval('dialog.title "Open Error"')
    +        lx.eval('dialog.msg "ファイルが開けませんでした"')
    +        lx.eval('dialog.open')
    +    except RuntimeError:
    +        lx.out(sys.exc_info()[0])
    +
    +mqoImporter.py + +

    うまく動作してなかったので、修正して更新しました(2007/12/10)。

    + +

    使い方

    +
      +
    1. mqoImporter.pyをダウンロード
    2. +
    3. System > Run Script(F6)
    4. +
    5. ダイアログが出てくるので、mqoImporter.py を選択
    6. +
    7. もう一度、ダイアログが出てくるので *.mqo ファイルを選択してしばらく待てばOK
    8. +
    +

    まだ、ミラーとか反映していなかったり、Material とかも無視しているので実用レベルではないですが、読み込みはできるようになったという感じです。
    +これからもちょくちょく、機能追加していきます。

    + +

    たまに、エラーが出て読み込めなくなってしまうので、そのときは modo を再起動してください。

    ]]> +
    +
    + + + 沖縄Twitterオフ無事終了ー + + tag:cellfusion.s49.coreserver.jp,2007:/blog//2.614 + + 2007-12-07T15:10:03Z + 2008-07-27T10:33:40Z + + 初幹事だった沖縄Twitterオフ、無事終わりましたー。 幹事が最後に到着とか... + + Mk-10:cellfusion + http://www.cellfusion.jp/ + + + + + + + + + 初幹事だった沖縄Twitterオフ、無事終わりましたー。
    +幹事が最後に到着とかさすが沖縄という感じくらいの遅れっぷりでした。
    +ほんと申し訳ないです。

    + +

    参加してくれたみんなのおかげで無事成功でした、
    +ありがとうございます。

    + +

    意外と暇つぶしで作った名刺が好評でした(入れ物がでかすぎだけどね) +2回目以降もたぶんちゃんとやりますよ。
    +次は時間通りに参加できるように頑張ります。

    + +

    参加者のレポ

    + + + +

    このイベントでなぜかマイミクが増えました(笑。

    +]]> + + +
    +
    + +
    Index: /as3/Syndication/trunk/tests/xml/minaco-atom.xml =================================================================== --- /as3/Syndication/trunk/tests/xml/minaco-atom.xml (リビジョン 952) +++ /as3/Syndication/trunk/tests/xml/minaco-atom.xml (リビジョン 952) @@ -0,0 +1,274 @@ + + MinaLoぐぅぅ + 一人暮らしの料理ぶろぐ + + 2008-07-22T17:54:21Z + WordPress + + + http://blog.minaco.net/feed/atom + + + + + minaco + http:// + + <![CDATA[SparkProjectの勉強会]]> + + http://blog.minaco.net/archives/187 + 2008-07-22T17:46:49Z + 2008-07-22T17:46:49Z + + + + + minaco + http:// + + <![CDATA[買っちゃったよ♪]]> + + http://blog.minaco.net/archives/186 + 2008-07-12T15:27:22Z + 2008-07-12T15:27:22Z + + + + + minaco + http:// + + <![CDATA[なすとひき肉]]> + + http://blog.minaco.net/archives/185 + 2008-07-06T14:56:47Z + 2008-07-06T14:56:47Z + + + + + minaco + http:// + + <![CDATA[水菜と豚肉っっっ]]> + + http://blog.minaco.net/archives/184 + 2008-06-18T16:49:01Z + 2008-06-18T16:49:01Z + + + + + minaco + http:// + + <![CDATA[Soumen]]> + + http://blog.minaco.net/archives/183 + 2008-06-15T11:47:01Z + 2008-06-15T11:47:01Z + + + + + minaco + http:// + + <![CDATA[野菜たっぷりのキムチちゃーはん]]> + + http://blog.minaco.net/archives/182 + 2008-06-13T16:28:20Z + 2008-06-13T16:28:20Z + + + + + minaco + http:// + + <![CDATA[もやし炒め と もろもろ。]]> + + http://blog.minaco.net/archives/181 + 2008-06-11T15:23:15Z + 2008-06-11T15:23:15Z + + + + + minaco + http:// + + <![CDATA[ほいこうろう]]> + + http://blog.minaco.net/archives/180 + 2008-06-08T16:03:24Z + 2008-06-08T16:03:24Z + + + + + minaco + http:// + + <![CDATA[ホームパーティ de Wii大会! ]]> + + http://blog.minaco.net/archives/179 + 2008-05-25T13:53:13Z + 2008-05-25T13:53:13Z + + + + + minaco + http:// + + <![CDATA[朝ごはんー]]> + + http://blog.minaco.net/archives/178 + 2008-05-04T03:28:21Z + 2008-05-04T03:28:21Z + + + Index: /as3/Syndication/trunk/tests/xml/berian-rss.xml =================================================================== --- /as3/Syndication/trunk/tests/xml/berian-rss.xml (リビジョン 952) +++ /as3/Syndication/trunk/tests/xml/berian-rss.xml (リビジョン 952) @@ -0,0 +1,859 @@ + + + + + + + + + belog + http://d.hatena.ne.jp/berian/ + belog + + berian + 2008-05-15T17:24:47+09:00 + + + + + + + + + + + + + + + [技術][Flash][ActionScript][Papervision3D]Papervision3Dで背景抜きFLV再生 + http://d.hatena.ne.jp/berian/20080515#1210839801 + Papervision3DのVideoStreamMaterialでFLV(AfterEffectsで背景抜きしたFLV)を再生させようと思ったら、 素直に背景が透明な状態で表示してくれなかったのでメモ。(2008/5/15 17:13 現在の最新リビジョン557) 実際の表示結果としては、背景部分がVideoStreamMaterial.fillC + + +

    Papervision3DのVideoStreamMaterialでFLV(AfterEffectsで背景抜きしたFLV)を再生させようと思ったら、

    +

    素直に背景が透明な状態で表示してくれなかったのでメモ。(2008/5/15 17:13 現在の最新リビジョン557)

    +

    実際の表示結果としては、背景部分がVideoStreamMaterial.fillColorで塗り潰されてしまう。

    +
    + +

    VideoStreamMaterialでは、生成したVideoオブジェクトを絶えずBitmapDataにdrawする事で、あたかも3D空間内で動画が再生されているように表現している。

    +

    ここで、

    + + +

    VideoStreamMaterial.as(一部抜粋)

    +
    +public override function updateBitmap ():void
    +{
    +    try
    +    {
    +        // copies the scale properties of the video
    +        var myMatrix:Matrix = new Matrix();
    +        myMatrix.scale( this.video.scaleX, this.video.scaleY );
    +        
    +        // Fills the rectangle with a background color
    +        this.bitmap.fillRect ( this.bitmap.rect, this.fillColor );
    +        
    +        // Due to security reasons the BitmapData cannot access RTMP content like a NetStream using a FMS server.
    +        // The next three lines are a simple but effective workaround to get pass Flash its security sandbox.
    +        //this.video.attachNetStream ( null );
    +        this.bitmap.draw( this.video, myMatrix, this.video.transform.colorTransform );
    +        this.video.attachNetStream ( this.stream );
    +    }catch(e:Error)
    +    {
    +        //
    +        trace(e);
    +    }
    +}
    +
    + +

    このdrawしてる部分。

    +

    自身のプロパティとしてBitmapDataを保持している。

    +

    では、このBitmapDataはいつ生成されているのか。

    +

    それは、継承元のMovieMaterialの下記の部分

    +

    (createBitmapFromSpriteメソッドでもbitmapをセットしていますが、今回問題になった処理ではないので。)

    +

    MovieMaterial.as(一部抜粋)

    +
    +protected function initBitmap( asset:DisplayObject ):void
    +{
    +    // Cleanup previous bitmap if needed
    +    if( bitmap )
    +        bitmap.dispose();
    +    
    +    // Create new bitmap
    +    bitmap = new BitmapData( asset.width, asset.height, this.movieTransparent );
    +}
    +
    + +

    ここで、「this.movieTransparent」。

    +

    これがtrueに設定されていないと、当たり前のように透明にはなりませんよねー。

    +

    じゃぁ、VideoStreamMaterialで、どのタイミングで設定できるのか?

    +

    設定するとなると、皆様はきっと下記のようにしますよね。

    +

    少なくとも、berianはそうしたくなります。

    +
    +var videoStreamMaterial:VideoStreamMaterial = new VideoStreamMaterial(video, stream);
    +videoStreamMaterial.movieTransparent = true;
    +
    + +

    だがしかし!!

    +

    だがしかしなのですYO!!

    +

    隊長!!

    +

    VideoStreamMaterialのインスタンスが生成された時点で、bitmapプロパティは作成済みであります!!

    +
    + +

    現状のVideoStreamMaterialでは、外から設定出来るタイミングが・・ありません。。。

    +

    残念だ・・。。

    +

    本当に残念だ・・。。

    +
    + +

    なので、VideoStreamMaterialのコンストラクタ引数に「transparent」を追加して、

    +

    「super」の引数にそれを追加してあげました。

    +

    以下、修正したVideoStreamMaterialコンストラクタ。

    +

    VideoStreamMaterial.as(一部抜粋)

    +
    +public function VideoStreamMaterial ( video:Video, stream:NetStream, transparent:Boolean = false )
    +{
    +    // store the values
    +    this.stream = stream;
    +    this.video = video;
    +    animated = true;
    +    
    +    // init the material with a listener for the NS object 
    +    initMaterial ( video, stream );
    +    
    +    /**
    +     * 実は、super(MovieMaterialコンストラクタ)の引数にはtransparentがあります。。
    +     * 
    +     * public function MovieMaterial( movieAsset:DiplayObject=null, transparent:Boolean=false, animated:Boolean=false )
    +     * {
    +     *
    +     *
    +     *
    +     * }
    +     */
    +    super ( DisplayObject(video), transparent );
    +}
    +
    + +

    これで背景抜きFLVが、めでたく表示されました。

    +
    + +

    本来はこうあるべきですよね!?

    +

    透過させると、何か他の問題が出てくるのかな??(もちろん負荷的な事以外に)

    +

    まぁ、もっと良い方法があれば、それに越した事はありませんが、とりあえずこれでw

    +

    でも、GreatWhiteでもこの部分は、今のところ(リビジョン557)特に変更ないしなー・・

    +

    とりあえず、試しにissueしとこうかな。

    + +]]>
    + berian + 2008-05-15T17:23:21+09:00 + 技術 + Flash + ActionScript + Papervision3D +
    + + [技術][Flash][ActionScript][Progression]Progressionの制作事例 + http://d.hatena.ne.jp/berian/20080424#1209049830 + このたび、berian初Progressionサイトがリリースされまして、 Progressionの制作事例に追加していただきました!! プロジェクト名「meica」です。 nium先生、ありがとうございます!! 今回、初めてProgressionを使用したサイトを作成しましたが、Progressionはホントに素 + + +

    このたび、berian初Progressionサイトがリリースされまして、

    +

    Progressionの制作事例に追加していただきました!!

    +

    プロジェクト名「meica」です。

    +

    nium先生、ありがとうございます!!

    +

    今回、初めてProgressionを使用したサイトを作成しましたが、Progressionはホントに素晴らしい!!

    +

    何かと手探りでしたが、それでも楽に開発が行えました!!

    +

    これからもProgressionでバリバリ開発していきまーす!!

    +
    + +

    まずは、Progression & Papervision3D!!

    + +]]>
    + berian + 2008-04-25T00:10:30+09:00 + 技術 + Flash + ActionScript + Progression +
    + + [技術][Flash][ActionScript][Entacl Develop]Entacl Develop -Theme3- + http://d.hatena.ne.jp/berian/20080314#1205487788 + 【今回の課題】 独自のトランジションクラスを作る! 【課題条件】 1.作ったクラスをimportして、1、2行宣言してあげるだけでMCに効果がつけられるようにする 2.どんな効果をつけるかは自由 って事で、今回はモザイクインを1行で行えるトランジションクラスを作成。 こ + + +

    【今回の課題】

    +

    独自のトランジションクラスを作る!

    +

    【課題条件】

    +

    1.作ったクラスをimportして、1、2行宣言してあげるだけでMCに効果がつけられるようにする

    +

    2.どんな効果をつけるかは自由

    +
    + +

    って事で、今回はモザイクインを1行で行えるトランジションクラスを作成。

    +
    + +

    このトランジションクラスを使用したサンプルが以下。

    + + +

    +

    Root.as(ドキュメントクラス)

    +
    +package {
    +
    +    import flash.display.DisplayObjectContainer;
    +    import flash.display.Sprite;
    +    import flash.display.StageAlign;
    +    import flash.events.MouseEvent;
    +
    +    import berian.transitions.mosaic.MosaicIn;
    +
    +    public class Root extends Sprite
    +    {
    +        private var image1:SampleImage;
    +        private var image2:SampleImage;
    +        private var image3:SampleImage;
    +
    +        public function Root():void
    +        {
    +            stage.scaleMode = "noScale";
    +            stage.align = StageAlign.TOP_LEFT;
    +
    +            this.image1 = addChild(new SampleImage("http://www.berian.org/belog/EntaclDevelop/theme3/1.jpg")) as SampleImage;
    +            this.image1.addEventListener(MouseEvent.CLICK, image1ClickHandler, false, 0, true);
    +
    +            this.image2 = addChild(new SampleImage("http://www.berian.org/belog/EntaclDevelop/theme3/2.jpg")) as SampleImage;
    +            this.image2.addEventListener(MouseEvent.CLICK, image2ClickHandler, false, 0, true);
    +            this.image2.x = 170;
    +        }
    +
    +        private function image1ClickHandler(event:MouseEvent):void
    +        {
    +			// この1行でモザイクイン!!
    +			// モザイクのサイズを小さめに
    +            MosaicIn.addMosaic(event.target.parent, { id: this.image1.name, showFlag: true, mosaicRatio: 0.1 });
    +        }
    +
    +        private function image2ClickHandler(event:MouseEvent):void
    +        {
    +			// この1行でモザイクイン!!
    +			// モザイクのサイズを大きめに
    +            MosaicIn.addMosaic(event.target.parent, { id: this.image2.name, showFlag: true, mosaicRatio: 0.7 });
    +        }
    +    }
    +}
    +
    + +

    SampleImage.as

    +
    +package
    +{
    +    import flash.display.MovieClip;
    +    import flash.display.Loader;
    +    import flash.events.Event;
    +    import flash.net.URLRequest;
    +
    +    import berian.transitions.mosaic.MosaicIn;
    +
    +    public class SampleImage extends MovieClip
    +    {
    +        private var mosaicId:String;
    +
    +        public function SampleImage(name:String):void
    +        {
    +            this.visible = false;
    +
    +            var loader:Loader = new Loader();
    +            loader.contentLoaderInfo.addEventListener(Event.COMPLETE, completeHandler, false, 0, true);
    +            loader.load(new URLRequest(name));
    +            addChild(loader);
    +        }
    +
    +        private function completeHandler(event:Event):void
    +        {
    +			// この1行でモザイクイン!!
    +            MosaicIn.addMosaic(this, { id: this.name, showFlag: true, mosaicRatio: 0.3 });
    +        }
    +    }
    +}
    +
    + +

    ソースはこちら

    +

    このサンプルでは、画像ロード時にモザイクインを行うのと、画像クリック時にモザイクインを行うようになっています。

    +

    重要なのは下記コードのみ。

    +
    +import berian.transitions.mosaic.MosaicIn;
    +MosaicIn.addMosaic(this, { id: this.name, showFlag: true, mosaicRatio: 0.3 });
    +
    + +

    MosaicInクラスをインポートして、addMosaicメソッドに必要な情報を渡すだけ。

    +

    簡単簡単。

    +

    作るのも簡単だった。

    +

    なにしろ、以前のブログで掲載したモザイクインをトランジションクラスとして修正しただけですから。。

    +

    楽してすいません。。

    +

    楽した分、今回作ったトランジションクラスは、出来る限りコーディング規約に則って書いてみた。

    +

    これからも、出来る限りコーディング規約に則って書いていこうと思います。

    +

    出来る限りですが。。

    +
    + +

    あ、忘れるところだった。

    +

    MosaicInクラスの仕様ですが・・・まぁソースを見てもらったらなんとなく分かるかと思いますwww

    + +]]>
    + berian + 2008-03-14T18:43:08+09:00 + 技術 + Flash + ActionScript + Entacl Develop +
    + + [技術][Flash][ActionScript][BulkLoader]BulkLoaderにはまった --その2-- + http://d.hatena.ne.jp/berian/20080313#1205336549 + 2008/03/13 10:16 更新 ロードされる側のBaseクラスのインスタンスが生成されるかどうか(コンストラクタが呼び出されているか)について記載していなかったので追記。 結論から言うと、ロードされる側のBaseクラスは、コンストラクタが呼び出されていませんでした。 実行側 + + +
    2008/03/13 10:16 更新
    +
    +ロードされる側のBaseクラスのインスタンスが生成されるかどうか(コンストラクタが呼び出されているか)について記載していなかったので追記。
    +
    +結論から言うと、ロードされる側のBaseクラスは、コンストラクタが呼び出されていませんでした。
    +
    +
    +実行側Rootをnew→実行側Baseをnew→ロード側Rectをnew→実行側Baseをnew
    +
    +
    +今回の検証で、外部swfをロードする際に注意すべき事として、下記が挙げられる。
    +その他にもあれば是非とも教えてください!
    +
    +・同じクラス名は使用しない。
    +・ロードされる側のドキュメントクラスではstageを参照出来ない。
    +
    + +
    + +

    前回の続きのお話です。

    +

    続きと言っても、はまった原因はFlashの仕様的な話です。

    +

    そもそも、berianが外部swfをロードするという事を今まで経験していなかった事が原因と思われる。。

    + + +

    以下、使用したBulkLoaderのリビジョンは186(2008/03/12現在の最新)です。

    +
    + +

    下記がロードされる側のコード。

    +

    Rect.as(ドキュメントクラス)

    +
    +package {
    +
    +	import flash.display.MovieClip;
    +
    +	public class Rect extends MovieClip {
    +
    +		public function Rect():void {
    +
    +			addChild(new Base());
    +		}
    +	}
    +}
    +
    + +

    Base.as

    +
    +package {
    +
    +	import flash.display.Sprite;
    +
    +	public class Base extends Sprite {
    +
    +		public function Base():void {
    +
    +			graphics.beginFill(0x000000);
    +			graphics.drawRect(0, 0, 300, 300);
    +			graphics.endFill();
    +		}
    +	}
    +}
    +
    + +

    単純に四角を描画しているだけです。

    +

    これをrect.swfとしてコンパイルして使用。

    +
    + +

    ちなみに、ドキュメントクラスRect.asがSpriteではなく、MovieClipを継承しているのは、BulkLoaderのgetMovieClipメソッドを使用して取得する事を想定しているためです。

    +
    + +

    次に、rect.swfをロードする側のコード

    +

    Root.as(ドキュメントクラス)

    +
    +package {
    +
    +	import flash.display.Sprite;
    +	import flash.display.StageAlign;
    +	import flash.display.StageQuality;
    +
    +	public class Root extends Sprite {
    +
    +		public function Root():void {
    +
    +			stage.scaleMode = "noScale";
    +			stage.align = StageAlign.TOP_LEFT;
    +			stage.quality = StageQuality.HIGH;
    +
    +			addChild(new Base());
    +		}
    +	}
    +}
    +
    + +

    Base.as

    +
    +package {
    +
    +	import flash.display.Sprite;
    +
    +	import br.com.stimuli.loading.BulkLoader;
    +	import br.com.stimuli.loading.BulkProgressEvent;
    +
    +	public class Base extends Sprite {
    +
    +		public function Base():void {
    +
    +			var bulkLoader:BulkLoader = new BulkLoader("Bulk Test");
    +			bulkLoader.add('rect.swf');
    +			bulkLoader.addEventListener(BulkLoader.COMPLETE, completeHandler);
    +			bulkLoader.start();
    +		}
    +
    +		private function completeHandler(e:BulkProgressEvent):void {
    +
    +			var bulkLoader:BulkLoader = BulkLoader.getLoader("Bulk Test");
    +			addChild(bulkLoader.getMovieClip('rect.swf'));
    +		}
    +	}
    +}
    +
    + +
    + +

    単純にrect.swfをロードしてaddChildしているだけです。

    +

    これをRoot.swfとしてコンパイルして実行すると・・

    +
    + +
    +Error: BulkLoader with name'Bulk Test' has already been created.
    +at br.com.stimuli.loading::BulkLoader()
    +at Base()
    +at Rect()
    +
    + +
    + +

    "Bulk Test"という名前でBulkLoaderインスタンスは既に作成されています!!(怒)・・と

    +
    + +

    いやいや・・ワタクシ2回もBulkLoaderコンストラクタ呼んでませんから・・

    +

    怒られる筋合いありませんから・・

    +
    + +

    デバッグしてみると、どうやらstartメソッドを実行したタイミングで、BulkLoaderコンストラクタがもう一度呼び出されているみたい。。

    +

    おかしいなぁ。。と思って、エラーメッセージをよーく見てみると、、

    +
    + +
    +at Base()
    +at Rect()
    +
    + +

    どうもエラー発生箇所がロードされる側のswfのようです。

    +
    + +

    なぜ・・!?!?!?

    +

    もうパニックですwww

    +
    + +

    ロードされる側のBaseクラスからBulkLoaderコンストラクタが呼び出されている・・

    +
    + +

    ・・・

    +
    + +

    ここでberian、やっと閃いた!!

    +

    実行するswf(Root.swf)にも、ロードされるswf(rect.swf)にもBaseクラスが存在する。

    +

    そして実行するswfのBaseクラスで、実際はBulkLoaderコンストラクタを呼び出している。

    +
    + +

    もしかして・・!!

    +
    + +

    って事で、実行するswf(Root.swf)のBaseクラスをBulkクラスにクラス名を変更。

    +

    Root.as(ドキュメントクラス)

    +
    +package {
    +
    +	import flash.display.Sprite;
    +	import flash.display.StageAlign;
    +	import flash.display.StageQuality;
    +
    +	public class Root extends Sprite {
    +
    +		public function Root():void {
    +
    +			stage.scaleMode = "noScale";
    +			stage.align = StageAlign.TOP_LEFT;
    +			stage.quality = StageQuality.HIGH;
    +
    +			addChild(new Bulk());
    +		}
    +	}
    +}
    +
    + +

    Bulk.as

    +
    +package {
    +
    +	import flash.display.Sprite;
    +
    +	import br.com.stimuli.loading.BulkLoader;
    +	import br.com.stimuli.loading.BulkProgressEvent;
    +
    +	public class Bulk extends Sprite {
    +
    +		public function Bulk():void {
    +
    +			var bulkLoader:BulkLoader = new BulkLoader("Bulk Test");
    +			bulkLoader.add('rect.swf');
    +			bulkLoader.addEventListener(BulkLoader.COMPLETE, completeHandler);
    +			bulkLoader.start();
    +		}
    +
    +		private function completeHandler(e:BulkProgressEvent):void {
    +
    +			var bulkLoader:BulkLoader = BulkLoader.getLoader("Bulk Test");
    +			addChild(bulkLoader.getMovieClip('rect.swf'));
    +		}
    +	}
    +}
    +
    + +

    処理は何も変えずにクラス名のみ変更してあります。

    +
    + +

    これをRoot.swfとしてコンパイルし、実行すると・・

    +
    + +
    + +
    + +

    おめでとーございまーす!!!

    +
    + +
    + +
    + +

    結局、何がどう悪さをしていたのかをまとめると。

    +

    【前提条件】

    +

    ・Root.swfにもrect.swfにもBaseクラスが存在した。

    +

    ・BulkLoaderのインスタンスを生成しているのはRoot.swfのBaseクラス。

    +
    + +

    【実際に行われた処理の流れ】

    +

    ・Root.swfでBaseクラスのインスタンスが生成される。

    +

    ・BaseクラスでBulkLoaderクラスのインスタンスが生成される。

    +

    ・BulkLoaderインスタンスのstartメソッドを実行する。

    +

    ・rect.swfがロードされる。

    +

    ・rect.swfが実行され、rect.swfのRectクラス→rect.swfのBaseクラスのインスタンスが順に生成される・・

    +

    と思いきや、Root.swfのBaseクラスのインスタンスがここでもう一度生成されてしまう。

    +

    これによって、結果的にBulkLoaderクラスのコンストラクタが2回呼ばれてしまったという事だった。

    +
    + +

    いやー、、この挙動は知らなかったなぁ。。

    +

    外部swfにロードする側と同じクラス名を使ってはいけないって事か。

    +

    完全に独立して動くものかと思ってたが。。

    +
    + +

    まぁ、勉強になったという事で!!

    + +]]>
    + berian + 2008-03-13T00:42:29+09:00 + 技術 + Flash + ActionScript + BulkLoader +
    + + [技術][Flash][ActionScript][BulkLoader]BulkLoaderにはまった --その1-- + http://d.hatena.ne.jp/berian/20080312#1205290718 + 2008/03/12 17:44 更新 Google Codeより下記の内容について[http://code.google.com/p/bulk-loader/issues/detail?id=27&can=1&sort=-id:title=New Issues]したところ、addメソッドでロードしてしまうのはバグという事でfixされました。 ソッコーで対応してくれ + + +
    2008/03/12 17:44 更新
    +
    +Google Codeより下記の内容について[http://code.google.com/p/bulk-loader/issues/detail?id=27&can=1&sort=-id:title=New Issues]したところ、addメソッドでロードしてしまうのはバグという事でfixされました。
    +
    +ソッコーで対応してくれました!
    +ありがたい事です。
    +
    + +
    + +

    t-matsuda氏から「BulkLoaderでgetMovieClipが動作しない!?」という質問があったので、動作検証を行おうとした時に、別の話ではまったのメモ。

    + + +

    以下、使用したBulkLoaderのリビジョンは180(2008/03/11現在の最新)です。

    +
    + +

    最初にgetMovieClipメソッドの検証を行おうと、下記のコード実行。

    +

    ソース抜粋

    +
    +package {
    +
    +	import flash.display.Sprite;
    +
    +	import br.com.stimuli.loading.BulkLoader;
    +	import br.com.stimuli.loading.BulkProgressEvent;
    +
    +	public class Base extends Sprite {
    +
    +		public function Base():void {
    +
    +			var bulkLoader:BulkLoader = new BulkLoader('Bulk');
    +
    +			bulkLoader.add('data.xml');
    +			bulkLoader.add('cloud.swf');
    +
    +			bulkLoader.addEventListener(BulkLoader.COMPLETE, completeHandler);
    +
    +			bulkLoader.start();
    +		}
    +
    +		private function completeHandler(e:BulkProgressEvent):void {
    +
    +			var bulkLoader:BulkLoader = BulkLoader.getLoader('Bulk');
    +			trace(bulkLoader.getXML('data.xml'));
    +			addChild(bulkLoader.getMovieClip('cloud.swf'));
    +		}
    +	}
    +}
    +
    + +
    + +

    ただ単純に「cloud.swf」をロードしているだけです。

    +

    これを実行すると下記のエラーが発生。

    +
    +TypeError: Error #1009: null のオブジェクト参照のプロパティまたはメソッドにアクセスすることはできません。
    +at Root()
    +
    + +
    + +

    ん??

    +

    この記事と少しエラーの内容が違うなぁ。。

    +
    + +

    まぁとりあえず、エラーが出たという事で下記のコードを実行。

    +

    ソース抜粋

    +
    +package {
    +
    +	import flash.display.Sprite;
    +
    +	import br.com.stimuli.loading.BulkLoader;
    +	import br.com.stimuli.loading.BulkProgressEvent;
    +
    +	public class Base extends Sprite {
    +
    +		public function Base():void {
    +
    +			var bulkLoader:BulkLoader = new BulkLoader('Bulk');
    +
    +			bulkLoader.add('data.xml');
    +			// コメントアウト
    +			//bulkLoader.add('cloud.swf');
    +
    +			bulkLoader.addEventListener(BulkLoader.COMPLETE, completeHandler);
    +
    +			bulkLoader.start();
    +		}
    +
    +		private function completeHandler(e:BulkProgressEvent):void {
    +
    +			var bulkLoader:BulkLoader = BulkLoader.getLoader('Bulk');
    +			trace(bulkLoader.getXML('data.xml'));
    +			// コメントアウト
    +			//addChild(bulkLoader.getMovieClip('cloud.swf'));
    +		}
    +	}
    +}
    +
    + +

    XMLのみロードするように修正。

    +

    問題無くXMLがトレースされた。

    +
    + +

    という事で、次に下記のコードを実行。

    +
    + +

    ソース抜粋

    +
    +package {
    +
    +	import flash.display.Sprite;
    +
    +	import br.com.stimuli.loading.BulkLoader;
    +	import br.com.stimuli.loading.BulkProgressEvent;
    +
    +	public class Base extends Sprite {
    +
    +		public function Base():void {
    +
    +			var bulkLoader:BulkLoader = new BulkLoader('Bulk');
    +
    +			bulkLoader.add('cloud.swf');
    +
    +			// コメントアウト
    +			//bulkLoader.addEventListener(BulkLoader.COMPLETE, completeHandler);
    +
    +			// コメントアウト
    +			//bulkLoader.start();
    +		}
    +
    +		private function completeHandler(e:BulkProgressEvent):void {
    +
    +			var bulkLoader:BulkLoader = BulkLoader.getLoader('Bulk');
    +			addChild(bulkLoader.getMovieClip('cloud.swf'));
    +		}
    +	}
    +}
    +
    + +
    + +

    addして終了する何の意味もないコード。

    +
    + +

    これを実行すると・・またしても同じエラーが!!

    +
    +TypeError: Error #1009: null のオブジェクト参照のプロパティまたはメソッドにアクセスすることはできません。
    +at Root()
    +
    + +
    + +

    なぜ!?!?!?

    +
    + +

    明らかにaddメソッドでロードしようとしてる・・

    +
    + +

    って事で、BulkLoaderのソースを追ってみた。

    +
    + +

    BulkLoader.asのソース抜粋

    +
    +	public function add(url : *, props : Object= null ) : LoadingItem {
    +				・
    +				・ 省略
    +				・
    +		item._addedTime = getTimer();
    +		item._additionIndex = _additionIndex;
    +		// add a lower priority than default, else the event for all items complete will fire before
    +		// individual listerners attached to the item
    +		item.addEventListener(Event.COMPLETE, _onItemComplete, false, int.MIN_VALUE, true);
    +		item.addEventListener(ERROR, _onItemError, false, 0, true);
    +		item.addEventListener(Event.OPEN, _onItemStarted, false, 0, true);
    +		item.addEventListener(ProgressEvent.PROGRESS, _onProgress, false, 0, true);
    +		_items.push(item);
    +		_itemsTotal += 1;
    +		_totalWeight += item.weight;
    +		sortItemsByPriority();
    +		_isFinished = false;
    +		if (!_isPaused){
    +			/**
    +				addメソッドを呼び出すと、ここの_loadNextが実行され、実際にファイルをロードする。。
    +			*/
    +			_loadNext();
    +		}
    +		return item;
    +	}
    +
    + +
    + +

    完全にロードしてます。。

    +

    addメソッドで。。

    +
    + +

    と言う事は・・

    +
    + +

    ソース抜粋

    +
    +package {
    +
    +	import flash.display.Sprite;
    +
    +	import br.com.stimuli.loading.BulkLoader;
    +	import br.com.stimuli.loading.BulkProgressEvent;
    +
    +	public class Base extends Sprite {
    +
    +		public function Base():void {
    +
    +			var bulkLoader:BulkLoader = new BulkLoader('Bulk');
    +
    +			bulkLoader.addEventListener(BulkLoader.COMPLETE, completeHandler);
    +
    +			bulkLoader.add('data.xml');
    +			bulkLoader.add('1.jpg');
    +		}
    +
    +		private function completeHandler(e:BulkProgressEvent):void {
    +
    +			var bulkLoader:BulkLoader = BulkLoader.getLoader('Bulk');
    +			trace(bulkLoader.getXML('data.xml'));
    +			addChild(bulkLoader.getBitmap('1.jpg'));
    +		}
    +	}
    +}
    +
    + +
    + +

    確かに・・XMLはトレースされ、画像も表示されました。。

    +
    + +

    BulkLoaderってaddメソッドでロードするんですね。。

    +

    addメソッドはただロード対象を登録するだけで、実際ロードするのはstartメソッドが呼び出されたタイミングなのかと思ってた。

    +

    完全にカルチャーショック!!

    +
    + +

    じゃぁ、startメソッドって何か意味があるのだろうか・・?

    +
    + +

    それともberianが何か大きな勘違いをしているのか??

    +

    不安だ。

    +

    誰か・・berianが間違ってるのかどうか、突っ込んでください!!

    + +]]>
    + berian + 2008-03-12T11:58:38+09:00 + 技術 + Flash + ActionScript + BulkLoader +
    +
    Index: /as3/Syndication/trunk/tests/xml/berian-rss2.xml =================================================================== --- /as3/Syndication/trunk/tests/xml/berian-rss2.xml (リビジョン 952) +++ /as3/Syndication/trunk/tests/xml/berian-rss2.xml (リビジョン 952) @@ -0,0 +1,890 @@ + + + + belog + http://d.hatena.ne.jp/berian/ + belog + berian + + + + [技術][Flash][ActionScript][Papervision3D]Papervision3Dで背景抜きFLV再生 + http://d.hatena.ne.jp/berian/20080515#1210839801 + + +

    Papervision3DのVideoStreamMaterialでFLV(AfterEffectsで背景抜きしたFLV)を再生させようと思ったら、

    +

    素直に背景が透明な状態で表示してくれなかったのでメモ。(2008/5/15 17:13 現在の最新リビジョン557)

    +

    実際の表示結果としては、背景部分がVideoStreamMaterial.fillColorで塗り潰されてしまう。

    +
    + +

    VideoStreamMaterialでは、生成したVideoオブジェクトを絶えずBitmapDataにdrawする事で、あたかも3D空間内で動画が再生されているように表現している。

    +

    ここで、

    + + +

    VideoStreamMaterial.as(一部抜粋)

    +
    +public override function updateBitmap ():void
    +{
    +    try
    +    {
    +        // copies the scale properties of the video
    +        var myMatrix:Matrix = new Matrix();
    +        myMatrix.scale( this.video.scaleX, this.video.scaleY );
    +        
    +        // Fills the rectangle with a background color
    +        this.bitmap.fillRect ( this.bitmap.rect, this.fillColor );
    +        
    +        // Due to security reasons the BitmapData cannot access RTMP content like a NetStream using a FMS server.
    +        // The next three lines are a simple but effective workaround to get pass Flash its security sandbox.
    +        //this.video.attachNetStream ( null );
    +        this.bitmap.draw( this.video, myMatrix, this.video.transform.colorTransform );
    +        this.video.attachNetStream ( this.stream );
    +    }catch(e:Error)
    +    {
    +        //
    +        trace(e);
    +    }
    +}
    +
    + +

    このdrawしてる部分。

    +

    自身のプロパティとしてBitmapDataを保持している。

    +

    では、このBitmapDataはいつ生成されているのか。

    +

    それは、継承元のMovieMaterialの下記の部分

    +

    (createBitmapFromSpriteメソッドでもbitmapをセットしていますが、今回問題になった処理ではないので。)

    +

    MovieMaterial.as(一部抜粋)

    +
    +protected function initBitmap( asset:DisplayObject ):void
    +{
    +    // Cleanup previous bitmap if needed
    +    if( bitmap )
    +        bitmap.dispose();
    +    
    +    // Create new bitmap
    +    bitmap = new BitmapData( asset.width, asset.height, this.movieTransparent );
    +}
    +
    + +

    ここで、「this.movieTransparent」。

    +

    これがtrueに設定されていないと、当たり前のように透明にはなりませんよねー。

    +

    じゃぁ、VideoStreamMaterialで、どのタイミングで設定できるのか?

    +

    設定するとなると、皆様はきっと下記のようにしますよね。

    +

    少なくとも、berianはそうしたくなります。

    +
    +var videoStreamMaterial:VideoStreamMaterial = new VideoStreamMaterial(video, stream);
    +videoStreamMaterial.movieTransparent = true;
    +
    + +

    だがしかし!!

    +

    だがしかしなのですYO!!

    +

    隊長!!

    +

    VideoStreamMaterialのインスタンスが生成された時点で、bitmapプロパティは作成済みであります!!

    +
    + +

    現状のVideoStreamMaterialでは、外から設定出来るタイミングが・・ありません。。。

    +

    残念だ・・。。

    +

    本当に残念だ・・。。

    +
    + +

    なので、VideoStreamMaterialのコンストラクタ引数に「transparent」を追加して、

    +

    「super」の引数にそれを追加してあげました。

    +

    以下、修正したVideoStreamMaterialコンストラクタ。

    +

    VideoStreamMaterial.as(一部抜粋)

    +
    +public function VideoStreamMaterial ( video:Video, stream:NetStream, transparent:Boolean = false )
    +{
    +    // store the values
    +    this.stream = stream;
    +    this.video = video;
    +    animated = true;
    +    
    +    // init the material with a listener for the NS object 
    +    initMaterial ( video, stream );
    +    
    +    /**
    +     * 実は、super(MovieMaterialコンストラクタ)の引数にはtransparentがあります。。
    +     * 
    +     * public function MovieMaterial( movieAsset:DiplayObject=null, transparent:Boolean=false, animated:Boolean=false )
    +     * {
    +     *
    +     *
    +     *
    +     * }
    +     */
    +    super ( DisplayObject(video), transparent );
    +}
    +
    + +

    これで背景抜きFLVが、めでたく表示されました。

    +
    + +

    本来はこうあるべきですよね!?

    +

    透過させると、何か他の問題が出てくるのかな??(もちろん負荷的な事以外に)

    +

    まぁ、もっと良い方法があれば、それに越した事はありませんが、とりあえずこれでw

    +

    でも、GreatWhiteでもこの部分は、今のところ(リビジョン557)特に変更ないしなー・・

    +

    とりあえず、試しにissueしとこうかな。

    + +]]>
    + + berian + + Thu, 15 May 2008 08:23:21 GMT + + + + 技術 + + Flash + + ActionScript + + Papervision3D + + +
    + + + [技術][Flash][ActionScript][Progression]Progressionの制作事例 + http://d.hatena.ne.jp/berian/20080424#1209049830 + + +

    このたび、berian初Progressionサイトがリリースされまして、

    +

    Progressionの制作事例に追加していただきました!!

    +

    プロジェクト名「meica」です。

    +

    nium先生、ありがとうございます!!

    +

    今回、初めてProgressionを使用したサイトを作成しましたが、Progressionはホントに素晴らしい!!

    +

    何かと手探りでしたが、それでも楽に開発が行えました!!

    +

    これからもProgressionでバリバリ開発していきまーす!!

    +
    + +

    まずは、Progression & Papervision3D!!

    + +]]>
    + + berian + + Thu, 24 Apr 2008 15:10:30 GMT + + + + 技術 + + Flash + + ActionScript + + Progression + + +
    + + + [技術][Flash][ActionScript][Entacl Develop]Entacl Develop -Theme3- + http://d.hatena.ne.jp/berian/20080314#1205487788 + + +

    【今回の課題】

    +

    独自のトランジションクラスを作る!

    +

    【課題条件】

    +

    1.作ったクラスをimportして、1、2行宣言してあげるだけでMCに効果がつけられるようにする

    +

    2.どんな効果をつけるかは自由

    +
    + +

    って事で、今回はモザイクインを1行で行えるトランジションクラスを作成。

    +
    + +

    このトランジションクラスを使用したサンプルが以下。

    + + +

    +

    Root.as(ドキュメントクラス)

    +
    +package {
    +
    +    import flash.display.DisplayObjectContainer;
    +    import flash.display.Sprite;
    +    import flash.display.StageAlign;
    +    import flash.events.MouseEvent;
    +
    +    import berian.transitions.mosaic.MosaicIn;
    +
    +    public class Root extends Sprite
    +    {
    +        private var image1:SampleImage;
    +        private var image2:SampleImage;
    +        private var image3:SampleImage;
    +
    +        public function Root():void
    +        {
    +            stage.scaleMode = "noScale";
    +            stage.align = StageAlign.TOP_LEFT;
    +
    +            this.image1 = addChild(new SampleImage("http://www.berian.org/belog/EntaclDevelop/theme3/1.jpg")) as SampleImage;
    +            this.image1.addEventListener(MouseEvent.CLICK, image1ClickHandler, false, 0, true);
    +
    +            this.image2 = addChild(new SampleImage("http://www.berian.org/belog/EntaclDevelop/theme3/2.jpg")) as SampleImage;
    +            this.image2.addEventListener(MouseEvent.CLICK, image2ClickHandler, false, 0, true);
    +            this.image2.x = 170;
    +        }
    +
    +        private function image1ClickHandler(event:MouseEvent):void
    +        {
    +			// この1行でモザイクイン!!
    +			// モザイクのサイズを小さめに
    +            MosaicIn.addMosaic(event.target.parent, { id: this.image1.name, showFlag: true, mosaicRatio: 0.1 });
    +        }
    +
    +        private function image2ClickHandler(event:MouseEvent):void
    +        {
    +			// この1行でモザイクイン!!
    +			// モザイクのサイズを大きめに
    +            MosaicIn.addMosaic(event.target.parent, { id: this.image2.name, showFlag: true, mosaicRatio: 0.7 });
    +        }
    +    }
    +}
    +
    + +

    SampleImage.as

    +
    +package
    +{
    +    import flash.display.MovieClip;
    +    import flash.display.Loader;
    +    import flash.events.Event;
    +    import flash.net.URLRequest;
    +
    +    import berian.transitions.mosaic.MosaicIn;
    +
    +    public class SampleImage extends MovieClip
    +    {
    +        private var mosaicId:String;
    +
    +        public function SampleImage(name:String):void
    +        {
    +            this.visible = false;
    +
    +            var loader:Loader = new Loader();
    +            loader.contentLoaderInfo.addEventListener(Event.COMPLETE, completeHandler, false, 0, true);
    +            loader.load(new URLRequest(name));
    +            addChild(loader);
    +        }
    +
    +        private function completeHandler(event:Event):void
    +        {
    +			// この1行でモザイクイン!!
    +            MosaicIn.addMosaic(this, { id: this.name, showFlag: true, mosaicRatio: 0.3 });
    +        }
    +    }
    +}
    +
    + +

    ソースはこちら

    +

    このサンプルでは、画像ロード時にモザイクインを行うのと、画像クリック時にモザイクインを行うようになっています。

    +

    重要なのは下記コードのみ。

    +
    +import berian.transitions.mosaic.MosaicIn;
    +MosaicIn.addMosaic(this, { id: this.name, showFlag: true, mosaicRatio: 0.3 });
    +
    + +

    MosaicInクラスをインポートして、addMosaicメソッドに必要な情報を渡すだけ。

    +

    簡単簡単。

    +

    作るのも簡単だった。

    +

    なにしろ、以前のブログで掲載したモザイクインをトランジションクラスとして修正しただけですから。。

    +

    楽してすいません。。

    +

    楽した分、今回作ったトランジションクラスは、出来る限りコーディング規約に則って書いてみた。

    +

    これからも、出来る限りコーディング規約に則って書いていこうと思います。

    +

    出来る限りですが。。

    +
    + +

    あ、忘れるところだった。

    +

    MosaicInクラスの仕様ですが・・・まぁソースを見てもらったらなんとなく分かるかと思いますwww

    + +]]>
    + + berian + + Fri, 14 Mar 2008 09:43:08 GMT + + + + 技術 + + Flash + + ActionScript + + Entacl Develop + + +
    + + + [技術][Flash][ActionScript][BulkLoader]BulkLoaderにはまった --その2-- + http://d.hatena.ne.jp/berian/20080313#1205336549 + + +
    2008/03/13 10:16 更新
    +
    +ロードされる側のBaseクラスのインスタンスが生成されるかどうか(コンストラクタが呼び出されているか)について記載していなかったので追記。
    +
    +結論から言うと、ロードされる側のBaseクラスは、コンストラクタが呼び出されていませんでした。
    +
    +
    +実行側Rootをnew→実行側Baseをnew→ロード側Rectをnew→実行側Baseをnew
    +
    +
    +今回の検証で、外部swfをロードする際に注意すべき事として、下記が挙げられる。
    +その他にもあれば是非とも教えてください!
    +
    +・同じクラス名は使用しない。
    +・ロードされる側のドキュメントクラスではstageを参照出来ない。
    +
    + +
    + +

    前回の続きのお話です。

    +

    続きと言っても、はまった原因はFlashの仕様的な話です。

    +

    そもそも、berianが外部swfをロードするという事を今まで経験していなかった事が原因と思われる。。

    + + +

    以下、使用したBulkLoaderのリビジョンは186(2008/03/12現在の最新)です。

    +
    + +

    下記がロードされる側のコード。

    +

    Rect.as(ドキュメントクラス)

    +
    +package {
    +
    +	import flash.display.MovieClip;
    +
    +	public class Rect extends MovieClip {
    +
    +		public function Rect():void {
    +
    +			addChild(new Base());
    +		}
    +	}
    +}
    +
    + +

    Base.as

    +
    +package {
    +
    +	import flash.display.Sprite;
    +
    +	public class Base extends Sprite {
    +
    +		public function Base():void {
    +
    +			graphics.beginFill(0x000000);
    +			graphics.drawRect(0, 0, 300, 300);
    +			graphics.endFill();
    +		}
    +	}
    +}
    +
    + +

    単純に四角を描画しているだけです。

    +

    これをrect.swfとしてコンパイルして使用。

    +
    + +

    ちなみに、ドキュメントクラスRect.asがSpriteではなく、MovieClipを継承しているのは、BulkLoaderのgetMovieClipメソッドを使用して取得する事を想定しているためです。

    +
    + +

    次に、rect.swfをロードする側のコード

    +

    Root.as(ドキュメントクラス)

    +
    +package {
    +
    +	import flash.display.Sprite;
    +	import flash.display.StageAlign;
    +	import flash.display.StageQuality;
    +
    +	public class Root extends Sprite {
    +
    +		public function Root():void {
    +
    +			stage.scaleMode = "noScale";
    +			stage.align = StageAlign.TOP_LEFT;
    +			stage.quality = StageQuality.HIGH;
    +
    +			addChild(new Base());
    +		}
    +	}
    +}
    +
    + +

    Base.as

    +
    +package {
    +
    +	import flash.display.Sprite;
    +
    +	import br.com.stimuli.loading.BulkLoader;
    +	import br.com.stimuli.loading.BulkProgressEvent;
    +
    +	public class Base extends Sprite {
    +
    +		public function Base():void {
    +
    +			var bulkLoader:BulkLoader = new BulkLoader("Bulk Test");
    +			bulkLoader.add('rect.swf');
    +			bulkLoader.addEventListener(BulkLoader.COMPLETE, completeHandler);
    +			bulkLoader.start();
    +		}
    +
    +		private function completeHandler(e:BulkProgressEvent):void {
    +
    +			var bulkLoader:BulkLoader = BulkLoader.getLoader("Bulk Test");
    +			addChild(bulkLoader.getMovieClip('rect.swf'));
    +		}
    +	}
    +}
    +
    + +
    + +

    単純にrect.swfをロードしてaddChildしているだけです。

    +

    これをRoot.swfとしてコンパイルして実行すると・・

    +
    + +
    +Error: BulkLoader with name'Bulk Test' has already been created.
    +at br.com.stimuli.loading::BulkLoader()
    +at Base()
    +at Rect()
    +
    + +
    + +

    "Bulk Test"という名前でBulkLoaderインスタンスは既に作成されています!!(怒)・・と

    +
    + +

    いやいや・・ワタクシ2回もBulkLoaderコンストラクタ呼んでませんから・・

    +

    怒られる筋合いありませんから・・

    +
    + +

    デバッグしてみると、どうやらstartメソッドを実行したタイミングで、BulkLoaderコンストラクタがもう一度呼び出されているみたい。。

    +

    おかしいなぁ。。と思って、エラーメッセージをよーく見てみると、、

    +
    + +
    +at Base()
    +at Rect()
    +
    + +

    どうもエラー発生箇所がロードされる側のswfのようです。

    +
    + +

    なぜ・・!?!?!?

    +

    もうパニックですwww

    +
    + +

    ロードされる側のBaseクラスからBulkLoaderコンストラクタが呼び出されている・・

    +
    + +

    ・・・

    +
    + +

    ここでberian、やっと閃いた!!

    +

    実行するswf(Root.swf)にも、ロードされるswf(rect.swf)にもBaseクラスが存在する。

    +

    そして実行するswfのBaseクラスで、実際はBulkLoaderコンストラクタを呼び出している。

    +
    + +

    もしかして・・!!

    +
    + +

    って事で、実行するswf(Root.swf)のBaseクラスをBulkクラスにクラス名を変更。

    +

    Root.as(ドキュメントクラス)

    +
    +package {
    +
    +	import flash.display.Sprite;
    +	import flash.display.StageAlign;
    +	import flash.display.StageQuality;
    +
    +	public class Root extends Sprite {
    +
    +		public function Root():void {
    +
    +			stage.scaleMode = "noScale";
    +			stage.align = StageAlign.TOP_LEFT;
    +			stage.quality = StageQuality.HIGH;
    +
    +			addChild(new Bulk());
    +		}
    +	}
    +}
    +
    + +

    Bulk.as

    +
    +package {
    +
    +	import flash.display.Sprite;
    +
    +	import br.com.stimuli.loading.BulkLoader;
    +	import br.com.stimuli.loading.BulkProgressEvent;
    +
    +	public class Bulk extends Sprite {
    +
    +		public function Bulk():void {
    +
    +			var bulkLoader:BulkLoader = new BulkLoader("Bulk Test");
    +			bulkLoader.add('rect.swf');
    +			bulkLoader.addEventListener(BulkLoader.COMPLETE, completeHandler);
    +			bulkLoader.start();
    +		}
    +
    +		private function completeHandler(e:BulkProgressEvent):void {
    +
    +			var bulkLoader:BulkLoader = BulkLoader.getLoader("Bulk Test");
    +			addChild(bulkLoader.getMovieClip('rect.swf'));
    +		}
    +	}
    +}
    +
    + +

    処理は何も変えずにクラス名のみ変更してあります。

    +
    + +

    これをRoot.swfとしてコンパイルし、実行すると・・

    +
    + +
    + +
    + +

    おめでとーございまーす!!!

    +
    + +
    + +
    + +

    結局、何がどう悪さをしていたのかをまとめると。

    +

    【前提条件】

    +

    ・Root.swfにもrect.swfにもBaseクラスが存在した。

    +

    ・BulkLoaderのインスタンスを生成しているのはRoot.swfのBaseクラス。

    +
    + +

    【実際に行われた処理の流れ】

    +

    ・Root.swfでBaseクラスのインスタンスが生成される。

    +

    ・BaseクラスでBulkLoaderクラスのインスタンスが生成される。

    +

    ・BulkLoaderインスタンスのstartメソッドを実行する。

    +

    ・rect.swfがロードされる。

    +

    ・rect.swfが実行され、rect.swfのRectクラス→rect.swfのBaseクラスのインスタンスが順に生成される・・

    +

    と思いきや、Root.swfのBaseクラスのインスタンスがここでもう一度生成されてしまう。

    +

    これによって、結果的にBulkLoaderクラスのコンストラクタが2回呼ばれてしまったという事だった。

    +
    + +

    いやー、、この挙動は知らなかったなぁ。。

    +

    外部swfにロードする側と同じクラス名を使ってはいけないって事か。

    +

    完全に独立して動くものかと思ってたが。。

    +
    + +

    まぁ、勉強になったという事で!!

    + +]]>
    + + berian + + Wed, 12 Mar 2008 15:42:29 GMT + + + + 技術 + + Flash + + ActionScript + + BulkLoader + + +
    + + + [技術][Flash][ActionScript][BulkLoader]BulkLoaderにはまった --その1-- + http://d.hatena.ne.jp/berian/20080312#1205290718 + + +
    2008/03/12 17:44 更新
    +
    +Google Codeより下記の内容について[http://code.google.com/p/bulk-loader/issues/detail?id=27&can=1&sort=-id:title=New Issues]したところ、addメソッドでロードしてしまうのはバグという事でfixされました。
    +
    +ソッコーで対応してくれました!
    +ありがたい事です。
    +
    + +
    + +

    t-matsuda氏から「BulkLoaderでgetMovieClipが動作しない!?」という質問があったので、動作検証を行おうとした時に、別の話ではまったのメモ。

    + + +

    以下、使用したBulkLoaderのリビジョンは180(2008/03/11現在の最新)です。

    +
    + +

    最初にgetMovieClipメソッドの検証を行おうと、下記のコード実行。

    +

    ソース抜粋

    +
    +package {
    +
    +	import flash.display.Sprite;
    +
    +	import br.com.stimuli.loading.BulkLoader;
    +	import br.com.stimuli.loading.BulkProgressEvent;
    +
    +	public class Base extends Sprite {
    +
    +		public function Base():void {
    +
    +			var bulkLoader:BulkLoader = new BulkLoader('Bulk');
    +
    +			bulkLoader.add('data.xml');
    +			bulkLoader.add('cloud.swf');
    +
    +			bulkLoader.addEventListener(BulkLoader.COMPLETE, completeHandler);
    +
    +			bulkLoader.start();
    +		}
    +
    +		private function completeHandler(e:BulkProgressEvent):void {
    +
    +			var bulkLoader:BulkLoader = BulkLoader.getLoader('Bulk');
    +			trace(bulkLoader.getXML('data.xml'));
    +			addChild(bulkLoader.getMovieClip('cloud.swf'));
    +		}
    +	}
    +}
    +
    + +
    + +

    ただ単純に「cloud.swf」をロードしているだけです。

    +

    これを実行すると下記のエラーが発生。

    +
    +TypeError: Error #1009: null のオブジェクト参照のプロパティまたはメソッドにアクセスすることはできません。
    +at Root()
    +
    + +
    + +

    ん??

    +

    この記事と少しエラーの内容が違うなぁ。。

    +
    + +

    まぁとりあえず、エラーが出たという事で下記のコードを実行。

    +

    ソース抜粋

    +
    +package {
    +
    +	import flash.display.Sprite;
    +
    +	import br.com.stimuli.loading.BulkLoader;
    +	import br.com.stimuli.loading.BulkProgressEvent;
    +
    +	public class Base extends Sprite {
    +
    +		public function Base():void {
    +
    +			var bulkLoader:BulkLoader = new BulkLoader('Bulk');
    +
    +			bulkLoader.add('data.xml');
    +			// コメントアウト
    +			//bulkLoader.add('cloud.swf');
    +
    +			bulkLoader.addEventListener(BulkLoader.COMPLETE, completeHandler);
    +
    +			bulkLoader.start();
    +		}
    +
    +		private function completeHandler(e:BulkProgressEvent):void {
    +
    +			var bulkLoader:BulkLoader = BulkLoader.getLoader('Bulk');
    +			trace(bulkLoader.getXML('data.xml'));
    +			// コメントアウト
    +			//addChild(bulkLoader.getMovieClip('cloud.swf'));
    +		}
    +	}
    +}
    +
    + +

    XMLのみロードするように修正。

    +

    問題無くXMLがトレースされた。

    +
    + +

    という事で、次に下記のコードを実行。

    +
    + +

    ソース抜粋

    +
    +package {
    +
    +	import flash.display.Sprite;
    +
    +	import br.com.stimuli.loading.BulkLoader;
    +	import br.com.stimuli.loading.BulkProgressEvent;
    +
    +	public class Base extends Sprite {
    +
    +		public function Base():void {
    +
    +			var bulkLoader:BulkLoader = new BulkLoader('Bulk');
    +
    +			bulkLoader.add('cloud.swf');
    +
    +			// コメントアウト
    +			//bulkLoader.addEventListener(BulkLoader.COMPLETE, completeHandler);
    +
    +			// コメントアウト
    +			//bulkLoader.start();
    +		}
    +
    +		private function completeHandler(e:BulkProgressEvent):void {
    +
    +			var bulkLoader:BulkLoader = BulkLoader.getLoader('Bulk');
    +			addChild(bulkLoader.getMovieClip('cloud.swf'));
    +		}
    +	}
    +}
    +
    + +
    + +

    addして終了する何の意味もないコード。

    +
    + +

    これを実行すると・・またしても同じエラーが!!

    +
    +TypeError: Error #1009: null のオブジェクト参照のプロパティまたはメソッドにアクセスすることはできません。
    +at Root()
    +
    + +
    + +

    なぜ!?!?!?

    +
    + +

    明らかにaddメソッドでロードしようとしてる・・

    +
    + +

    って事で、BulkLoaderのソースを追ってみた。

    +
    + +

    BulkLoader.asのソース抜粋

    +
    +	public function add(url : *, props : Object= null ) : LoadingItem {
    +				・
    +				・ 省略
    +				・
    +		item._addedTime = getTimer();
    +		item._additionIndex = _additionIndex;
    +		// add a lower priority than default, else the event for all items complete will fire before
    +		// individual listerners attached to the item
    +		item.addEventListener(Event.COMPLETE, _onItemComplete, false, int.MIN_VALUE, true);
    +		item.addEventListener(ERROR, _onItemError, false, 0, true);
    +		item.addEventListener(Event.OPEN, _onItemStarted, false, 0, true);
    +		item.addEventListener(ProgressEvent.PROGRESS, _onProgress, false, 0, true);
    +		_items.push(item);
    +		_itemsTotal += 1;
    +		_totalWeight += item.weight;
    +		sortItemsByPriority();
    +		_isFinished = false;
    +		if (!_isPaused){
    +			/**
    +				addメソッドを呼び出すと、ここの_loadNextが実行され、実際にファイルをロードする。。
    +			*/
    +			_loadNext();
    +		}
    +		return item;
    +	}
    +
    + +
    + +

    完全にロードしてます。。

    +

    addメソッドで。。

    +
    + +

    と言う事は・・

    +
    + +

    ソース抜粋

    +
    +package {
    +
    +	import flash.display.Sprite;
    +
    +	import br.com.stimuli.loading.BulkLoader;
    +	import br.com.stimuli.loading.BulkProgressEvent;
    +
    +	public class Base extends Sprite {
    +
    +		public function Base():void {
    +
    +			var bulkLoader:BulkLoader = new BulkLoader('Bulk');
    +
    +			bulkLoader.addEventListener(BulkLoader.COMPLETE, completeHandler);
    +
    +			bulkLoader.add('data.xml');
    +			bulkLoader.add('1.jpg');
    +		}
    +
    +		private function completeHandler(e:BulkProgressEvent):void {
    +
    +			var bulkLoader:BulkLoader = BulkLoader.getLoader('Bulk');
    +			trace(bulkLoader.getXML('data.xml'));
    +			addChild(bulkLoader.getBitmap('1.jpg'));
    +		}
    +	}
    +}
    +
    + +
    + +

    確かに・・XMLはトレースされ、画像も表示されました。。

    +
    + +

    BulkLoaderってaddメソッドでロードするんですね。。

    +

    addメソッドはただロード対象を登録するだけで、実際ロードするのはstartメソッドが呼び出されたタイミングなのかと思ってた。

    +

    完全にカルチャーショック!!

    +
    + +

    じゃぁ、startメソッドって何か意味があるのだろうか・・?

    +
    + +

    それともberianが何か大きな勘違いをしているのか??

    +

    不安だ。

    +

    誰か・・berianが間違ってるのかどうか、突っ込んでください!!

    + +]]>
    + + berian + + Wed, 12 Mar 2008 02:58:38 GMT + + + + 技術 + + Flash + + ActionScript + + BulkLoader + + +
    + +
    +
    Index: /as3/Syndication/trunk/tests/xml/cellfusion-rss2.xml =================================================================== --- /as3/Syndication/trunk/tests/xml/cellfusion-rss2.xml (リビジョン 952) +++ /as3/Syndication/trunk/tests/xml/cellfusion-rss2.xml (リビジョン 952) @@ -0,0 +1,533 @@ + + + + cellfusion blog + http://blog.cellfusion.jp/ + + ja + Copyright 2008 + Sun, 10 Aug 2008 21:13:41 +0900 + http://www.sixapart.com/movabletype/ + http://www.rssboard.org/rss-specification + + + 今さら「はて☆スタ」つけた + 記事に対しての反応とかを見たかったから、今さらだけど はてなスター つけてみた。

    ]]>
    + http://blog.cellfusion.jp/archives/634/ + http://blog.cellfusion.jp/archives/634/ + + Diary + + + Sun, 10 Aug 2008 21:13:41 +0900 +
    + + + DisplayObject.transform.matrix + いままで Sprite でズーム表現をするためには、Flash で下記のように基準点を中心に持ってくるか、Sprite を入れ子にするという方法を使ってたんだけど。

    + +

    基準点を設定

    + +

    それってどうしても一手間かかるし、何よりも基準点を移動させると AS で弄るときに座標系が混乱してくるのでどうにか方法はないのかなと探っていたら DisplayObject.transform.matrix を使うと左上が基準点でもオブジェクトの真ん中を基準として動かす事ができた!

    + +

    コードは下記の通り

    + + + +
    package  
    +{
    +	import flash.display.Sprite;
    +	import flash.geom.Matrix;
    +	import flash.geom.Transform;	
    +	
    +	public class TransformTest extends Sprite 
    +	{
    +		private var _sp:Sprite;
    +		
    +		public function TransformTest()
    +		{
    +			_sp = new Sprite();
    +			_sp.x = 150;
    +			_sp.y = 150;
    +			
    +			// 四角形を作る
    +			_sp.graphics.beginFill(0x000000);
    +			_sp.graphics.drawRect(0, 0, 100, 100);
    +			_sp.graphics.endFill();
    +			
    +			// 基準点をわかりやすくするために左上に赤い矩形を作る
    +			_sp.graphics.beginFill(0xFF0000);
    +			_sp.graphics.drawRect(0, 0, 5, 5);
    +			_sp.graphics.endFill();
    +			
    +			// 変換用の Matrix を準備
    +			var mat:Matrix = new Matrix();
    +			
    +			// 回転の中心点を変えるために -50 する
    +			mat.translate(-50, -50);
    +			
    +			// 回転する
    +			mat.rotate(45*Math.PI/180);
    +			
    +			// 元の位置に戻す
    +			mat.translate(50, 50);
    +			
    +			// 現在表示している matrix と合体させる
    +			mat.concat(_sp.transform.matrix);
    +			
    +			trace("before:"+_sp.transform.matrix);
    +			
    +			// 中心点で回転させるための Matrix を反映する
    +			_sp.transform.matrix = mat;
    +			
    +			trace("after:"+_sp.transform.matrix);
    +			trace("rotation:"+_sp.rotation);
    +			
    +			addChild(_sp);
    +		}
    +	}
    +}
    + + + +

    特殊なのが

    + +
    _sp.transform.matrix = mat;
    + +

    の部分。直接いじれないので、別に Matrix を作成して合成して反映している。ココ以外は Matrix の使い方を知っていればそのままの知識が使える。

    + +

    DisplayObject.transform.matrix を使う事で Sprite 関係は基本的に左上を基準点として作成すれば座標系で混乱する事もなるし、今まで以上にアニメーションの幅も広がるよね。

    + +

    ちょっと上のコードだと動いてるのかわかりにくいので、enterFrame でくるくる回してみた。

    + + + +
    package  
    +{
    +	import flash.display.Sprite;
    +	import flash.events.Event;
    +	import flash.geom.Matrix;	
    +	
    +	public class TransformEnterFrame extends Sprite 
    +	{
    +		private var _sp:Sprite;
    +
    +		public function TransformEnterFrame()
    +		{
    +			_sp = new Sprite();
    +			_sp.x = 150;
    +			_sp.y = 150;
    +			
    +			// 四角形を作る
    +			_sp.graphics.beginFill(0x000000);
    +			_sp.graphics.drawRect(0, 0, 100, 100);
    +			_sp.graphics.endFill();
    +			
    +			// 基準点をわかりやすくするために左上に赤い矩形を作る
    +			_sp.graphics.beginFill(0xFF0000);
    +			_sp.graphics.drawRect(0, 0, 5, 5);
    +			_sp.graphics.endFill();
    +			
    +			addEventListener(Event.ENTER_FRAME,	enterframeHandler);
    +			
    +			addChild(_sp);
    +		}
    +		
    +		private function enterframeHandler(event:Event):void
    +		{
    +			var mat:Matrix = new Matrix();
    +			mat.translate(-50, -50);
    +			
    +			// 5°ずつ回転させる
    +			mat.rotate(5*Math.PI/180);
    +			
    +			mat.translate(50, 50);
    +			mat.concat(_sp.transform.matrix);
    +			_sp.transform.matrix = mat;
    +			
    +			// 座標がどうなっているのか trace
    +//			trace("x:"+_sp.x, "y:"+_sp.y);
    +		}
    +	}
    +}
    + + + +

    これでオブジェクトの基準点じゃなくて、中心で回ってるのがよくわかると思う。

    + +

    transform.matrix は Flash8 くらいからあるので、AS2.0 を使っている人でも同じ使い方で使用できると思う。

    + +

    今回の サンプルファイル

    + +

    他には fl.motion.MatrixTransformer とか使ってもできそうな感じ。後でこいつも触ってみよう。

    + +

    Tweener でこのプロパティを使いたい場合は fladdict さんの MatrixShortcut.as を使うといいよ!
    +fladdict» ブログアーカイブ » Tweener拡張で、MovieClipをMatrixで超変形をできるようにした

    ]]>
    + http://blog.cellfusion.jp/archives/633/ + http://blog.cellfusion.jp/archives/633/ + + AS3.0 + + + transform matrix as3 flash anime + + Thu, 07 Aug 2008 18:43:18 +0900 +
    + + + Flash IDE のヘルプをブラウザで見る方法 + 今まで気づいてなかったのもだいぶ問題ありなんですが、Flash IDE のヘルプは HTML なのでブラウザでも見れるよ!
    +OSX だと下記のディレクトリに格納されてるみたい。

    + + + +
    file:///Library/Application%20Support/Adobe/Flash%20CS3/ja/Configuration/HelpPanel/Help
    + + + +

    AS3 とか AS2 とか個別に格納されてるので、IDE の検索がいまいちだと思ってるならココを検索対象にして検索するといいんじゃないかな?

    + +

    HTML の場所の調べかたは

    + + +
      +
    1. Flash IDE のヘルプを適当に開く
    2. +
    3. 中のリンク部分を右クリック
    4. +
    5. 「リンクをコピー」って言うコンテキストメニューをクリック
    6. +
    7. コピーしたリンクをブラウザで開けばOK!
    8. +
    + + + +

    こうすれば、いちいちググってた人もローカルでさくさく作業ができるね!
    +あ、でも Flash の IDE をインストールしてる人だけだよ。

    + +

    さらに livedocs.adobe.com のリンクをローカルに書き換えてくれるグリモンがあれば完璧?
    +そこはエロイ人に任せた!

    ]]>
    + http://blog.cellfusion.jp/archives/632/ + http://blog.cellfusion.jp/archives/632/ + + AS2.0 + + AS3.0 + + Memo + + + Wed, 06 Aug 2008 11:16:36 +0900 +
    + + + AS でカレンダーみたいな表示するよ! + ikacr4u @cellfusion にっ日本語でおk!(  今日中に作れとか言われてバカ言ってんじゃねーよって感じです。ソース落ちてないしもうめんどい。(

    + +

    と ikacr4u が寂しい事言ってたのを ASer としては見過ごせないので、簡単な AS サンプル作っちゃうよ!

    + +

    hoge という識別子が着いた MovieClip の中には tf という TextField がある想定だよ!
    +とりあえず、今月のカレンダーを作成する方法。

    + + + +
    // 何も引数をつけないと今現在の日付が入ったDateができる
    +var date:Date = new Date();
    +// 月の初めの日付にする
    +date.setDate(1);
    +// 月の初めの曜日を取得
    +var day:Number = date.getDay();
    +
    +// 日付分を for で回す(めんどくさいので31固定)
    +for (var i:Number = 0; i < 31; i++) {
    +  var num:Number = i + day;
    +  // x の値を求めるために、 7 で割ったあまりを xpos に入れる
    +  var xpos:Number = num % 7;
    +  // y の値を求めるために 7 で割って切り下げする
    +  var ypos:Number = Math.floor(num / 7);
    +  
    +  // MovieClip を作成
    +  var mc:MovieClip = attachMovie("hoge", "hoge"+i, i);
    +  // 作成した MovieClip の x 値を xpos を参考に設定
    +  mc._x = xpos * 40;
    +  // y 値を ypos を参考に設定
    +  mc._y = ypos * 30;
    +
    +  mc.tf.text = i;
    +}
    + + + +

    サンプル as_calendar.fla

    + +

    とりあえず、簡単に説明してみた。
    +図とか入れた方がわかりやすそうなので、あとで更新するよ。

    ]]>
    + http://blog.cellfusion.jp/archives/631/ + http://blog.cellfusion.jp/archives/631/ + + AS2.0 + + + Thu, 31 Jul 2008 18:25:28 +0900 +
    + + + DS-10 届いてた! + メール便だったのでおそらく土曜日には着いていたっぽい、会社のポストに突き刺さってました・・・。

    + +

    届いてたDS-10

    + +

    早速、Demo-1 を流しながら KAOSSPAD とかで遊んでみたけど、これ楽しすぎるなぁ。初めてのシンセサイザーなのでこれからじっくり触ってみる!

    ]]>
    + http://blog.cellfusion.jp/archives/629/ + http://blog.cellfusion.jp/archives/629/ + + Diary + + Game + + + Mon, 28 Jul 2008 09:58:28 +0900 +
    + + + ようやく再始動 + Twitter に慣れすぎてなかなか blog に戻ってこれなかったけど、今日から少しずつ再始動していくよ!
    +というわけで、ようやくデフォルトのテンプレートから変更しました。といってもだいぶ突貫なので Mac でしか確認してなかったりするので、うまく見えてない方はごめんなさい・・・。徐々にいじっていきます!
    +上の検索部分も作り方が悪かったのかうまく動いていなかったり・・・、後で直すから今は勘弁してー!

    + +

    あと、今まで permalink が日付と番号という訳のわからない組み合わせになっていたんですが、これからは「記事ID」にしたので基本変わることはないと思います・・・・たぶん。
    +なぜか ID が 300 とかから始まってるんですが・・・。

    ]]>
    + http://blog.cellfusion.jp/archives/627/ + http://blog.cellfusion.jp/archives/627/ + + Diary + + + Sun, 27 Jul 2008 20:06:05 +0900 +
    + + + サーバーばっかりさわってるな + ちょっと前に TIG を入れてからずっとサーバーとかいじってるよ!

    + +

    最近は mobirc を make するために CPAN からライブラリを落としてきたり、足りないものがあったら apt-get したり・・・いろいろやってるうちにちょっとずつ詳しくなってきている気がする。
    +正直、仕事でサーバーとかいじってる人は尊敬する。

    + +

    そんなわけで、昨日は Plagger いれたり FFmpeg 入れたりしました。
    +特に何かするわけじゃないんですが、サーバーいじりが楽しいです。

    + +

    mobirc は config.yaml がよくわからなくてまだ動いてないですけど・・・。

    + +

    もうちょっとしたら、先週のアニメイトオフ(別名:@holynight のメイド女装オフ)のエントリーでもするかなー。

    ]]>
    + http://blog.cellfusion.jp/archives/625/ + http://blog.cellfusion.jp/archives/625/ + + Diary + + + Sat, 26 Jul 2008 13:40:14 +0900 +
    + + + TIG が動くようになった! + 苦節数ヶ月・・・ようやく TIG がまともに動くようになったよ!

    + +

    @shunirr が TIG を活用しているのを見て、自分も使いたいと思って鯖にインストールしたけど、ログがうまくとれなくて今まで放置してた。
    +けど、さっきようやくログがとれるようになったよ!

    + +

    忘れないようにメモっておく。

    ]]>
    + http://blog.cellfusion.jp/archives/624/ + http://blog.cellfusion.jp/archives/624/ + + + Sun, 20 Jul 2008 13:43:20 +0900 +
    + + + バイクがおかしくなった + バイクがおかしくなってはじめてメンテナンスの偉大さに気付く駄目ライダーなのです。
    +ちょっと前からアクセルを思いっきり開けると回転数が落ちてストールするようになってたのですが(その時点でバイク屋に持って行けば良かったんですよね・・・)、引っ越しとかと重なって結局そのまま乗ってたらエンジンすらかかりにくくなってしまいましたーorz

    + +

    今頃あわててもしょうがないけど、取りあえず自分で直せそうなところはやってみようと土日を使ってメンテナンスしました(写真撮っておけば良かった)。

    + +

    やったことはこんな感じ。
    +全く知識がないので本とか、ググったりしながら作業。

    + + +
      +
    • エンジンオイル交換(ついでにフィルター交換)
    • +
    • スパークプラグ交換
    • +
    • エアクリーナー交換
    • +
    + + + +

    どうせ触るならと思ってエンジンオイルとかも交換しつつ、色々やってみたけど特に変わらず・・・。
    +エンジンはかかるけど、思いっきり開けるとやっぱり駄目だった。

    + +

    どうやら、キャブとかが怪しいらしい・・・そのへんは今の自分では触れなさそうなので、明日近所のバイク屋さんに持って行くことにするー。
    +金額がアレだったら、頑張って自力でするしかないなー。

    + +

    だがそれより先に、明日からの出勤をどうするかが問題だ!

    ]]>
    + http://blog.cellfusion.jp/archives/623/ + http://blog.cellfusion.jp/archives/623/ + + Bike + + Diary + + + bike diary + + Sun, 22 Jun 2008 20:02:55 +0900 +
    + + + Flash Switcher入れてみた(OSX版) + Firefox 3.0 RC 1 がリリースされたのでついでにインストールしてみた。

    + +

    まず、「 Flash Switcher って何?」っていう人に説明。
    +Flash Switcher っていうのは、ブラウザに入っている Flash Player をいちいちインストールしなくても手軽に変更できる Firefox の便利プラグインです。

    + +

    普通にインストールするだけだとうまくいかなかったので作業手順をメモ。
    +ついでに、簡単な操作方法も書いておく。

    ]]>
    + http://blog.cellfusion.jp/archives/622/ + http://blog.cellfusion.jp/archives/622/ + + Flash + + Memo + + + Thu, 22 May 2008 01:56:58 +0900 +
    + + + そろそろターニングポイントな気がする + 気がついたら3ヶ月以上放置してましたね。
    +最近はほとんど Twitter にいるのでついつい Blog を置き去りにしすぎました。

    + +

    ここんところゆるやかにだけど少しずつ周りの環境に変化があって、自分もそろそろ受けな行動は終わりにしてもっと攻めな行動を行おうかなと、気がついたら今年で25歳だしもうそろそろターニングポイントな気がする。

    + +

    東京とか別の土地に行きたいからそろそろ動き出さないとな。

    ]]>
    + http://blog.cellfusion.jp/archives/621/ + http://blog.cellfusion.jp/archives/621/ + + Diary + + + Fri, 25 Apr 2008 11:54:00 +0900 +
    + + + SocketURLLoader + URLLoader だと RequestHeader とかうまくつけられなかったので OZACC.blog: URLLoaderで紹介されてた。 +as3httpclient を Downloads から落としてきて使ってたつもりが、何度試してもうまくいかないので何故かと思っていたら、SVN と Downloads の中がまるっきり別物でした・・・orz

    + +

    Downloads に含まれているのは HTTPURLLoader っていうクラスでなんだか中途半端な状態なので、POSTとかでクエリが渡せません。 +ちゃんと SVN から落としましょー。ということでメモ。

    + +
    svn checkout http://as3httpclient.googlecode.com/svn/trunk/
    +
    +]]>
    + http://blog.cellfusion.jp/archives/619/ + http://blog.cellfusion.jp/archives/619/ + + AS3.0 + + + AS3 + + library + + URLLoader + + Mon, 21 Jan 2008 13:44:36 +0900 +
    + + + サーバーで保存したSharedObjectはローカルでも参照できるよ + すいません、これ自分の操作ミスでローカルでも参照できると勘違いしてただけです。
    実際はドメインごとにSharedObjectが保存されているので、とれないとのことです。

    +

    ドキュメントにもさりげなく書かれていた・・・ドキュメントは一度目を通す癖をつけなくちゃ

    + +

    ブラウザの Cokkie のようなFlashのSharedObjectは保存したURLでしか参照できないような感じがするけど、設定次第ではローカルのswfからでも参照できるよ!

    + +

    たとえば、こんな風な使い方もできる。 +

      +
    1. サイト上でスクリーンセーバーの設定をする
    2. +
    3. SharedObjectに保存
    4. +
    5. スクリーンセーバーのswfからSharedObjectにアクセス
    6. +
    +うまく使えば、おもしろいことができそう。

    ]]>
    + http://blog.cellfusion.jp/archives/617/ + http://blog.cellfusion.jp/archives/617/ + + AS2.0 + + + ActionScript2.0 + + Flash + + SharedObject + + Sat, 05 Jan 2008 18:24:40 +0900 +
    + + + mqoフォーマットをmodoでも読み込めるスクリプト書いた + まだ、Mterialとかいろいろできてないんだけど、取りあえずVertexとPolyをインポートできるようになったので公開しておく。
    +スクリプトは勉強がてらに Python で書いてみたよ。

    ]]>
    + http://blog.cellfusion.jp/archives/615/ + http://blog.cellfusion.jp/archives/615/ + + modo + + + 3D + + Impoter + + Metaseqoia + + modo + + Python + + Sat, 08 Dec 2007 21:25:44 +0900 +
    + + + 沖縄Twitterオフ無事終了ー + 初幹事だった沖縄Twitterオフ、無事終わりましたー。
    +幹事が最後に到着とかさすが沖縄という感じくらいの遅れっぷりでした。
    +ほんと申し訳ないです。

    + +

    参加してくれたみんなのおかげで無事成功でした、
    +ありがとうございます。

    + +

    意外と暇つぶしで作った名刺が好評でした(入れ物がでかすぎだけどね) +2回目以降もたぶんちゃんとやりますよ。
    +次は時間通りに参加できるように頑張ります。

    + +

    参加者のレポ

    + + + +

    このイベントでなぜかマイミクが増えました(笑。

    +]]>
    + http://blog.cellfusion.jp/archives/614/ + http://blog.cellfusion.jp/archives/614/ + + Diary + + + Okinawa + + Twitter + + Sat, 08 Dec 2007 00:10:03 +0900 +
    + +
    +
    Index: /as3/Syndication/trunk/tests/xml/minaco-rss2.xml =================================================================== --- /as3/Syndication/trunk/tests/xml/minaco-rss2.xml (リビジョン 952) +++ /as3/Syndication/trunk/tests/xml/minaco-rss2.xml (リビジョン 952) @@ -0,0 +1,320 @@ + + + + + + MinaLoぐぅぅ + http://blog.minaco.net + 一人暮らしの料理ぶろぐ + Tue, 22 Jul 2008 17:54:21 +0900 + http://wordpress.org/?v=ME2.2 + ja + + SparkProjectの勉強会 + http://blog.minaco.net/archives/187 + http://blog.minaco.net/archives/187#comments + Tue, 22 Jul 2008 17:46:49 +0900 + minaco + + + + http://blog.minaco.net/archives/187 + + http://blog.minaco.net/archives/187/feed + + + 買っちゃったよ♪ + http://blog.minaco.net/archives/186 + http://blog.minaco.net/archives/186#comments + Sat, 12 Jul 2008 15:27:22 +0900 + minaco + + + + http://blog.minaco.net/archives/186 + + http://blog.minaco.net/archives/186/feed + + + なすとひき肉 + http://blog.minaco.net/archives/185 + http://blog.minaco.net/archives/185#comments + Sun, 06 Jul 2008 14:56:47 +0900 + minaco + + + + + + + + http://blog.minaco.net/archives/185 + + http://blog.minaco.net/archives/185/feed + + + 水菜と豚肉っっっ + http://blog.minaco.net/archives/184 + http://blog.minaco.net/archives/184#comments + Wed, 18 Jun 2008 16:49:01 +0900 + minaco + + + + + + + + + + http://blog.minaco.net/archives/184 + + http://blog.minaco.net/archives/184/feed + + + Soumen + http://blog.minaco.net/archives/183 + http://blog.minaco.net/archives/183#comments + Sun, 15 Jun 2008 11:47:01 +0900 + minaco + + + + + + http://blog.minaco.net/archives/183 + + http://blog.minaco.net/archives/183/feed + + + 野菜たっぷりのキムチちゃーはん + http://blog.minaco.net/archives/182 + http://blog.minaco.net/archives/182#comments + Fri, 13 Jun 2008 16:28:20 +0900 + minaco + + + + + + http://blog.minaco.net/archives/182 + + http://blog.minaco.net/archives/182/feed + + + もやし炒め と もろもろ。 + http://blog.minaco.net/archives/181 + http://blog.minaco.net/archives/181#comments + Wed, 11 Jun 2008 15:23:15 +0900 + minaco + + + + + + + + + + http://blog.minaco.net/archives/181 + + http://blog.minaco.net/archives/181/feed + + + ほいこうろう + http://blog.minaco.net/archives/180 + http://blog.minaco.net/archives/180#comments + Sun, 08 Jun 2008 16:03:24 +0900 + minaco + + + + + + + + http://blog.minaco.net/archives/180 + + http://blog.minaco.net/archives/180/feed + + + ホームパーティ de Wii大会!  + http://blog.minaco.net/archives/179 + http://blog.minaco.net/archives/179#comments + Sun, 25 May 2008 13:53:13 +0900 + minaco + + + + + + + + + + + + http://blog.minaco.net/archives/179 + + http://blog.minaco.net/archives/179/feed + + + 朝ごはんー + http://blog.minaco.net/archives/178 + http://blog.minaco.net/archives/178#comments + Sun, 04 May 2008 03:28:21 +0900 + minaco + + + + + + + + http://blog.minaco.net/archives/178 + + http://blog.minaco.net/archives/178/feed + + + Index: /as3/Syndication/trunk/tests/TestApplication.as =================================================================== --- /as3/Syndication/trunk/tests/TestApplication.as (リビジョン 952) +++ /as3/Syndication/trunk/tests/TestApplication.as (リビジョン 952) @@ -0,0 +1,16 @@ +package +{ + import flash.display.Sprite; + + import org.libspark.as3unit.runner.AS3UnitCore; + + import org.libspark.syndication.AllTests; + + public class TestApplication extends Sprite + { + public function TestApplication() + { + AS3UnitCore.main(AllTests); + } + } +} Index: /as3/Syndication/trunk/tests/org/libspark/asunit/extensions/TestSetup.as =================================================================== --- /as3/Syndication/trunk/tests/org/libspark/asunit/extensions/TestSetup.as (リビジョン 952) +++ /as3/Syndication/trunk/tests/org/libspark/asunit/extensions/TestSetup.as (リビジョン 952) @@ -0,0 +1,78 @@ +/* + * Copyright(c) 2006 the Spark project. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, + * either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + */ + +package org.libspark.asunit.extensions +{ + import org.libspark.asunit.framework.Protectable; + import org.libspark.asunit.framework.Test; + import org.libspark.asunit.framework.TestResult; + + /** + * A Decorator to set up and tear down additional fixture state. Subclass + * TestSetup and insert it into your tests when you want to set up additional + * state once before the tests are run. + */ + public class TestSetup extends TestDecorator + { + public function TestSetup(test:Test) + { + super(test); + } + + public override function run(result:TestResult):void + { + var p:Protectable = new ProtectableClosure(function():void + { + setUp(); + basicRun(result); + tearDown(); + }); + result.runProtected(this, p); + } + + /** + * Sets up the fixture. Override to set up additional fixture state. + */ + protected function setUp():void + { + } + + /** + * Tears down the fixture. Override to tear down the additional fixture + * state. + */ + protected function tearDown():void + { + } + } +} + +import org.libspark.asunit.framework.Protectable; + +class ProtectableClosure implements Protectable +{ + private var func:Function; + + public function ProtectableClosure(f:Function) + { + func = f; + } + + public function protect():void + { + func(); + } +} Index: /as3/Syndication/trunk/tests/org/libspark/asunit/extensions/TestDecorator.as =================================================================== --- /as3/Syndication/trunk/tests/org/libspark/asunit/extensions/TestDecorator.as (リビジョン 952) +++ /as3/Syndication/trunk/tests/org/libspark/asunit/extensions/TestDecorator.as (リビジョン 952) @@ -0,0 +1,65 @@ +/* + * Copyright(c) 2006 the Spark project. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, + * either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + */ + +package org.libspark.asunit.extensions +{ + import org.libspark.asunit.framework.Assert; + import org.libspark.asunit.framework.Test; + import org.libspark.asunit.framework.TestResult; + + /** + * A Decorator for Tests. Use TestDecorator as the base class for defining new + * test decorators. Test decorator subclasses can be introduced to add behaviour + * before or after a test is run. + */ + public class TestDecorator extends Assert implements Test + { + protected var fTest:Test; + + public function TestDecorator(test:Test) + { + fTest = test; + } + + /** + * The basic run behaviour + */ + public function basicRun(result:TestResult):void + { + fTest.run(result); + } + + public function countTestCases():int + { + return fTest.countTestCases(); + } + + public function run(result:TestResult):void + { + basicRun(result); + } + + public function toString():String + { + return String(fTest); + } + + public function get test():Test + { + return fTest; + } + } +} Index: /as3/Syndication/trunk/tests/org/libspark/asunit/extensions/RepeatedTest.as =================================================================== --- /as3/Syndication/trunk/tests/org/libspark/asunit/extensions/RepeatedTest.as (リビジョン 952) +++ /as3/Syndication/trunk/tests/org/libspark/asunit/extensions/RepeatedTest.as (リビジョン 952) @@ -0,0 +1,55 @@ +/* + * Copyright(c) 2006 the Spark project. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, + * either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + */ + +package org.libspark.asunit.extensions +{ + import org.libspark.asunit.framework.Test; + import org.libspark.asunit.framework.TestResult; + + /** + * A Decorator that runs a test repeatedly. + */ + public class RepeatedTest extends TestDecorator + { + private var timesRepeat:uint; + + public function RepeatedTest(test:Test, repeat:uint) + { + super(test); + timesRepeat = repeat; + } + + public override function countTestCases():int + { + return super.countTestCases() * timesRepeat; + } + + public override function run(result:TestResult):void + { + for (var i:uint = 0; i < timesRepeat; ++i) { + if (result.shouldStop) { + break; + } + super.run(result); + } + } + + public override function toString():String + { + return super.toString() + '(repeated)'; + } + } +} Index: /as3/Syndication/trunk/tests/org/libspark/asunit/textui/ResultPrinter.as =================================================================== --- /as3/Syndication/trunk/tests/org/libspark/asunit/textui/ResultPrinter.as (リビジョン 952) +++ /as3/Syndication/trunk/tests/org/libspark/asunit/textui/ResultPrinter.as (リビジョン 952) @@ -0,0 +1,134 @@ +/* + * Copyright(c) 2006 the Spark project. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, + * either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + */ + + package org.libspark.asunit.textui + { + import org.libspark.asunit.framework.AssertionFailedError; + import org.libspark.asunit.framework.Test; + import org.libspark.asunit.framework.TestFailure; + import org.libspark.asunit.framework.TestListener; + import org.libspark.asunit.framework.TestResult; + import org.libspark.asunit.runner.BaseTestRunner; + + public class ResultPrinter implements TestListener + { + private var buffer:String; + + public function ResultPrinter() + { + buffer = ""; + } + + public function print(result:TestResult, runTime:Number):void + { + if (buffer != "") { + trace(buffer); + } + printHeader(runTime); + printErrors(result); + printFailures(result); + printFooter(result); + } + + protected function printHeader(runTime:Number):void + { + trace(""); + trace("Time: " + (runTime / 1000)); + } + + protected function printErrors(result:TestResult):void + { + printDefects(result.errors, result.errorCount, "error"); + } + + protected function printFailures(result:TestResult):void + { + printDefects(result.failures, result.failureCount, "failure"); + } + + protected function printDefects(booBoos:Array, count:uint, type:String):void + { + if (count == 0) return; + if (count == 1) { + trace("There was " + count + " " + type + ":"); + } + else { + trace("There were " + count + " " + type + "s:"); + } + for (var i:uint = 0; i < booBoos.length; ++i) { + printDefect(TestFailure(booBoos[i]), i); + } + } + + public function printDefect(booBoo:TestFailure, count:uint):void + { + printDefectHeader(booBoo, count); + printDefectTrace(booBoo); + } + + protected function printDefectHeader(booBoo:TestFailure, count:uint):void + { + trace(count + ") " + booBoo.failedTest); + } + + protected function printDefectTrace(booBoo:TestFailure):void + { + trace(booBoo.trace); + } + + protected function printFooter(result:TestResult):void + { + if (result.wasSuccessful) { + trace(""); + trace("OK (" + result.runCount + "test" + (result.runCount == 1 ? "" : "s") + ")"); + } + else { + trace(""); + trace("FAILURES!!!"); + trace("Tests run: " + result.runCount + ", Failures: " + result.failureCount + ", Errors: " + result.errorCount); + } + trace(""); + } + + public function addError(test:Test, error:Object):void + { + bufferedTrace("E"); + } + + public function addFailure(test:Test, error:AssertionFailedError):void + { + bufferedTrace("F"); + } + + public function endTest(test:Test):void + { + } + + public function startTest(test:Test):void + { + bufferedTrace("."); + } + + private function bufferedTrace(message:String):void + { + buffer += message; + if (buffer.length >= 80) { + trace(buffer); + buffer = ""; + } + } + } + } Index: /as3/Syndication/trunk/tests/org/libspark/asunit/textui/TestRunner.as =================================================================== --- /as3/Syndication/trunk/tests/org/libspark/asunit/textui/TestRunner.as (リビジョン 952) +++ /as3/Syndication/trunk/tests/org/libspark/asunit/textui/TestRunner.as (リビジョン 952) @@ -0,0 +1,64 @@ +/* + * Copyright(c) 2006 the Spark project. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, + * either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + */ + + package org.libspark.asunit.textui + { + import org.libspark.asunit.framework.*; + import org.libspark.asunit.runner.*; + + import flash.utils.getTimer; + + public class TestRunner extends BaseTestRunner + { + private var printer:ResultPrinter; + + public function TestRunner() + { + printer = new ResultPrinter(); + } + + /** + * Runs a suite extracted from a TestCase subclass. + */ + static public function runSuite(testClass:Class):void + { + run(new TestSuite(testClass)); + } + + /** + * Runs a single test and collects its results. + * This method can be used to start a test run + * from your program. + */ + static public function run(test:Test):TestResult + { + var runner:TestRunner = new TestRunner(); + return runner.doRun(test); + } + + public function doRun(suite:Test):TestResult + { + var result:TestResult = new TestResult(); + result.addListener(printer); + var startTime:Number = getTimer(); + suite.run(result); + var endTime:Number = getTimer(); + var runTime:Number = endTime - startTime; + printer.print(result, runTime); + return result; + } + } + } Index: /as3/Syndication/trunk/tests/org/libspark/asunit/runner/TestRunListenerStatus.as =================================================================== --- /as3/Syndication/trunk/tests/org/libspark/asunit/runner/TestRunListenerStatus.as (リビジョン 952) +++ /as3/Syndication/trunk/tests/org/libspark/asunit/runner/TestRunListenerStatus.as (リビジョン 952) @@ -0,0 +1,32 @@ +/* + * Copyright(c) 2006 the Spark project. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, + * either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + */ + + package org.libspark.asunit.runner + { + public class TestRunListenerStatus + { + public static const ERROR:uint = 1; + public static const FAILURE:uint = 2; + + public function TestRunListenerStatus(privateClass:PrivateClass) + { + } + } + } + + class PrivateClass + { + } Index: /as3/Syndication/trunk/tests/org/libspark/asunit/runner/TestSuiteLoader.as =================================================================== --- /as3/Syndication/trunk/tests/org/libspark/asunit/runner/TestSuiteLoader.as (リビジョン 952) +++ /as3/Syndication/trunk/tests/org/libspark/asunit/runner/TestSuiteLoader.as (リビジョン 952) @@ -0,0 +1,26 @@ +/* + * Copyright(c) 2006 the Spark project. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, + * either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + */ + + package org.libspark.asunit.runner + { + /** + * An interface to define how a tst suite should be loaded. + */ + public interface TestSuiteLoader + { + function load(suiteClassName:String):Class; + } + } Index: /as3/Syndication/trunk/tests/org/libspark/asunit/runner/StandardTestSuiteLoader.as =================================================================== --- /as3/Syndication/trunk/tests/org/libspark/asunit/runner/StandardTestSuiteLoader.as (リビジョン 952) +++ /as3/Syndication/trunk/tests/org/libspark/asunit/runner/StandardTestSuiteLoader.as (リビジョン 952) @@ -0,0 +1,34 @@ +/* + * Copyright(c) 2006 the Spark project. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, + * either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + */ + + package org.libspark.asunit.runner + { + import flash.utils.getDefinitionByName; + + /** + * The standard test suite loader. + */ + public class StandardTestSuiteLoader implements TestSuiteLoader + { + /** + * Uses the getClassByName() to load the test class. + */ + public function load(suiteClassName:String):Class + { + return Class(getDefinitionByName(suiteClassName)); + } + } + } Index: /as3/Syndication/trunk/tests/org/libspark/asunit/runner/BaseTestRunner.as =================================================================== --- /as3/Syndication/trunk/tests/org/libspark/asunit/runner/BaseTestRunner.as (リビジョン 952) +++ /as3/Syndication/trunk/tests/org/libspark/asunit/runner/BaseTestRunner.as (リビジョン 952) @@ -0,0 +1,137 @@ +/* + * Copyright(c) 2006 the Spark project. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, + * either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + */ + + package org.libspark.asunit.runner + { + import org.libspark.asunit.framework.*; + + /** + * Base class for all test runners. + */ + public class BaseTestRunner implements TestListener + { + public static const SUITE_METHOD:String = "suite"; + + public function startTest(test:Test):void + { + testStarted(String(test)); + } + + public function endTest (test:Test):void + { + testEnded(String(test)); + } + + public function addError(test:Test, error:Object):void + { + testFailed(TestRunListenerStatus.ERROR, test, error); + } + + public function addFailure(test:Test, error:AssertionFailedError):void + { + testFailed(TestRunListenerStatus.FAILURE, test, error); + } + + // TestRunListener implementation + public function testStarted(testName:String):void + { + } + public function testEnded(testName:String):void + { + } + public function testFailed(status:uint, test:Test, error:Object):void + { + } + + /** + * Returns the Test corresponding to the given suite. This is + * a template method, subclasses override runFailed(), clearStatus(). + */ + public function getTest(suiteClassName:String):Test + { + if (suiteClassName.length == 0) { + clearStatus(); + return null; + } + var testClass:Class = null; + try { + testClass = loadSuiteClass(suiteClassName); + } + catch (e:ReferenceError) { + runFailed("Class not found \"" + e.message + "\""); + return null; + } + catch (e:Error) { + runFailed("Error: " + e.toString()); + return null; + } + + var suiteMethod:Function = null; + try { + suiteMethod = testClass[SUITE_METHOD]; + } + catch (e:Error) { + clearStatus(); + return new TestSuite(testClass); + } + + var test:Test = null; + try { + test = suiteMethod(); + if (test == null) { + return test; + } + } + catch (e:Error) { + runFailed("Failed to invoke suite(); " + e.toString()); + } + + clearStatus(); + return test; + } + + /** + * Override to defined how to handle a failed loading of + * a test suite. + */ + protected function runFailed(message:String):void + { + } + + /** + * Retun the loaded Class for a suite name + */ + protected function loadSuiteClass(suiteClassName:String):Class + { + return getLoader().load(suiteClassName); + } + + /** + * Clear the status message. + */ + protected function clearStatus():void + { + } + + /** + * Returns the loader to be used. + */ + public function getLoader():TestSuiteLoader + { + return new StandardTestSuiteLoader(); + } + } + } Index: /as3/Syndication/trunk/tests/org/libspark/asunit/framework/TestResult.as =================================================================== --- /as3/Syndication/trunk/tests/org/libspark/asunit/framework/TestResult.as (リビジョン 952) +++ /as3/Syndication/trunk/tests/org/libspark/asunit/framework/TestResult.as (リビジョン 952) @@ -0,0 +1,226 @@ +/* + * Copyright(c) 2006 the Spark project. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, + * either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + */ + +package org.libspark.asunit.framework +{ + /** + * A TestResult collects the results of executing + * a test case. It is an instance of the Collecting Parameter pattern. + * The test framework distinguishes between failures and erorrs. + * A failure is anticipated and checked for with assertions. Errors are + * unanticipated problems like an RangeError. + * + * @see Test + */ + import org.libspark.asunit.framework.Protectable; + + public class TestResult + { + protected var failures_:Array; + protected var errors_:Array; + protected var listeners:Array; + protected var runTests:int; + private var stop_:Boolean; + + public function TestResult() { + failures_ = new Array(); + errors_ = new Array(); + listeners = new Array(); + runTests = 0; + stop_ = false; + } + + /** + * Adds an error to the list of errors. + */ + public function addError(test:Test, e:Object):void + { + errors_.push(new TestFailure(test, e)); + eachListener(function(listener:TestListener):void { + listener.addError(test, e); + }); + } + + /** + * Adds a failure to the list of failures. + */ + public function addFailure(test:Test, e:AssertionFailedError):void + { + failures_.push(new TestFailure(test, e)); + eachListener(function(listener:TestListener):void { + listener.addFailure(test, e); + }); + } + + /** + * Registers a TestListener. + */ + public function addListener(listener:TestListener):void + { + listeners.push(listener); + } + + /** + * Unregisters a TestListener. + */ + public function removeListener(listener:TestListener):void + { + for (var i:uint = 0; i < listeners.length; ++i) { + if (listener[i] == listener) { + listeners = listeners.splice(i, 1); + break; + } + } + } + + protected function eachListener (f:Function):void + { + var listeners_:Array = listeners; + var count:uint = listeners_.length; + for (var i:uint = 0; i < count; ++i) { + f((listeners_[i] as TestListener)); + } + } + + /** + * Informs the result that a test was completed. + */ + public function endTest(test:Test):void + { + eachListener(function(listener:TestListener):void { + listener.endTest(test); + }); + } + + /** + * Gets the number of detected errors. + */ + public function get errorCount():uint + { + return errors_.length; + } + + /** + * Gets the array of errors. + */ + public function get errors():Array + { + return errors_; + } + + /** + * Gets the number of detected failures. + */ + public function get failureCount():uint + { + return failures_.length; + } + + /** + * Gets the array of failures. + */ + public function get failures():Array + { + return failures_; + } + + /** + * Run a TestCase. + */ + public function run(test:TestCase):void + { + startTest(test); + runProtected(test, new TestProtect(test)); + endTest(test); + } + + /** + * Runs a TestCase + */ + public function runProtected(test:Test, p:Protectable):void + { + try { + p.protect(); + } + catch (e:AssertionFailedError) { + addFailure(test, e); + } + catch (e:Object) { + addError(test, e); + } + } + + /** + * Gets the number of run tests. + */ + public function get runCount():uint + { + return runTests; + } + + /** + * Check the whether the test run should stop. + */ + public function get shouldStop():Boolean + { + return stop_; + } + + /** + * Informs the result that a test will be started. + */ + public function startTest(test:Test):void + { + runTests += test.countTestCases(); + eachListener(function(listener:TestListener):void { + listener.startTest(test); + }); + } + + /** + * Marks that the test run should stop. + */ + public function stop():void + { + stop_ = true; + } + + /** + * Returns whether the entire test was successful or not. + */ + public function get wasSuccessful():Boolean + { + return failureCount == 0 && errorCount == 0; + } + } +} + +import org.libspark.asunit.framework.Protectable; +import org.libspark.asunit.framework.TestCase; + +class TestProtect implements Protectable +{ + private var test:TestCase; + + public function TestProtect(test:TestCase) + { + this.test = test; + } + public function protect():void + { + test.runBare(); + } +} Index: /as3/Syndication/trunk/tests/org/libspark/asunit/framework/Test.as =================================================================== --- /as3/Syndication/trunk/tests/org/libspark/asunit/framework/Test.as (リビジョン 952) +++ /as3/Syndication/trunk/tests/org/libspark/asunit/framework/Test.as (リビジョン 952) @@ -0,0 +1,36 @@ +/* + * Copyright(c) 2006 the Spark project. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, + * either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + */ + +package org.libspark.asunit.framework +{ + /** + * A Test can be run and collect its results. + * + * @see TestResult + */ + public interface Test + { + /** + * Counts the number of test cases that will be run by this test. + */ + function countTestCases():int; + + /** + * Runs a test and collects its result in a TestResult instance. + */ + function run(result:TestResult):void; + } +} Index: /as3/Syndication/trunk/tests/org/libspark/asunit/framework/Assert.as =================================================================== --- /as3/Syndication/trunk/tests/org/libspark/asunit/framework/Assert.as (リビジョン 952) +++ /as3/Syndication/trunk/tests/org/libspark/asunit/framework/Assert.as (リビジョン 952) @@ -0,0 +1,218 @@ +/* + * Copyright(c) 2006 the Spark project. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, + * either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + */ + + package org.libspark.asunit.framework + { + import flash.utils.ByteArray; + + /** + * A set of asserft methods. Messages are only displayed when an assert fails. + */ + public class Assert + { + /** + * Asserts that a condition is true. If it isn't it throws + * an AssertionFailedError with the given message. + */ + static public function assertTrue(condition:Boolean, message:String=""):void + { + if (!condition) { + fail(message); + } + } + + /** + * Asserts that a condition is false. If it isn't it throws + * an AssertionFailedError with the given message. + */ + static public function assertFalse(condition:Boolean, message:String=""):void + { + assertTrue(!condition, message); + } + + /** + * Fails a test with the given message. + */ + static public function fail(message:String=""):void + { + throw new AssertionFailedError(message); + } + + /** + * Asserts that two objects are equal. If they are not + * an AssertionFailedError is thrown with the given message. + */ + static public function assertEquals(expected:*, actual:*, message:String=""):void + { + if (expected == null && actual == null) { + return; + } + if (expected != null) { + if (expected == actual) { + return; + } + if (expected is Array && actual is Array) { + assertArrayEquals(expected, actual, message); + return; + } + if (expected is ByteArray && actual is ByteArray) { + assertArrayEquals(expected, actual, message); + return; + } + if ('equals' in expected && expected.equals(actual)) { + return; + } + } + failNotEquals(expected, actual, message); + } + + /** + * Asserts that two objects refer to the same object. If they are not + * an AssertionFailedError is thrown with the given message. + * This method uses Strict Equality Operator (===) for comparation. + */ + static public function assertSame(expected:*, actual:*, message:String=""):void + { + if (expected === actual) { + return; + } + failNotSame(expected, actual, message); + } + + /** + * Asserts that two objects do not refer to the same object. If they are not + * an AssertionFailedError is thrown with the given message. + * This method uses Strict Equality Operator (===) for comparation. + */ + static public function assertNotSame(expected:*, actual:*, message:String=""):void + { + if (expected === actual) { + failSame(message); + } + } + + /** + * Asserts that an object isn't null. If it is + * an AssertionFailedError is thrown with the given message. + */ + static public function assertNotNull(object:*, message:String=""):void + { + assertTrue(object != null, message); + } + + /** + * Asserts that an object is null. If it is not + * an AssertionFailedError is thrown with the given message. + */ + static public function assertNull(object:*, message:String=""):void + { + assertTrue(object == null, message); + } + + /** + * Asserts that two arrays are equal. If they are not + * an AssertionFailedError is thrown with the given message. + */ + static public function assertArrayEquals(expected:Array, actual:Array, message:String=""):void + { + if (expected == actual) { + return; + } + + var header:String = message == "" ? "" : message + ": "; + + if (expected == null) { + fail(header + "expected array was null"); + } + if (actual == null) { + fail(header + "actual array was null"); + } + if (expected.length != actual.length) { + fail(header + "array lengths differed, expected.length=" + expected.length + " actual.length=" + actual.length); + } + + var len:uint = expected.length; + for (var index:uint = 0; index < len; ++index) { + + var expectedObject:* = expected[index]; + var actualObject:* = actual[index]; + + if (expectedObject is Array && actualObject is Array) { + assertArrayEquals(expectedObject, actualObject, header + "arrays first differed at element " + index + ";"); + } + else { + assertEquals(expectedObject, actualObject, header + "arrays first differed at element [" + index + "];"); + } + } + } + + /** + * Asserts that two ByteArrays are equal. If they are not + * an AssertionFailedError is thrown with the given message. + */ + static public function assertByteArrayEquals(expected:ByteArray, actual:ByteArray, message:String=""):void + { + if (expected == null && actual == null) { + return; + } + if (expected != null && (expected.length == actual.length)) { + var len:uint = expected.length; + var index:uint = 0; + for (; index < len; ++index) { + if (actual[index] != expected[index]) { + break; + } + } + if (index == len) { + return; + } + } + failNotEquals(byteArray2HexString(expected), byteArray2HexString(actual), message); + } + + static private function byteArray2HexString(bytes:ByteArray):String + { + var hex:String = "0123456789abcdef"; + var hexString:String = "0x"; + for (var i:uint = 0; i < bytes.length; ++i) { + var n:uint = bytes[i]; + hexString += hex.charAt((n >> 4) & 0xf) + hex.charAt(n & 0xf); + } + return hexString; + } + + static private function failNotEquals(expected:*, actual:*, message:String):void + { + fail((message != "" ? message + " " : "") + "expected:<" + expected + "> but was:<" + actual + ">"); + } + + static private function failSame(message:String):void + { + if (message != '') { + message += ' '; + } + fail(message + 'expected not same'); + } + + static private function failNotSame(expected:*, actual:*, message:String):void + { + if (message != '') { + message += ' '; + } + fail(message + 'expected same:<' + expected + '> was not:<' + actual + '>'); + } + } + } Index: /as3/Syndication/trunk/tests/org/libspark/asunit/framework/Protectable.as =================================================================== --- /as3/Syndication/trunk/tests/org/libspark/asunit/framework/Protectable.as (リビジョン 952) +++ /as3/Syndication/trunk/tests/org/libspark/asunit/framework/Protectable.as (リビジョン 952) @@ -0,0 +1,29 @@ +/* + * Copyright(c) 2006 the Spark project. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, + * either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + */ + + package org.libspark.asunit.framework + { + /** + * A Protectable can be run and can throw a error. + */ + public interface Protectable + { + /** + * Runs the the following method protected. + */ + function protect():void; + } + } Index: /as3/Syndication/trunk/tests/org/libspark/asunit/framework/TestListener.as =================================================================== --- /as3/Syndication/trunk/tests/org/libspark/asunit/framework/TestListener.as (リビジョン 952) +++ /as3/Syndication/trunk/tests/org/libspark/asunit/framework/TestListener.as (リビジョン 952) @@ -0,0 +1,44 @@ +/* + * Copyright(c) 2006 the Spark project. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, + * either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + */ + + package org.libspark.asunit.framework + { + /** + * A Listener for test progress. + */ + public interface TestListener + { + /** + * An error occurred. + */ + function addError(test:Test, error:Object):void; + + /** + * A failure occurred. + */ + function addFailure(test:Test, error:AssertionFailedError):void; + + /** + * A test ended. + */ + function endTest(test:Test):void; + + /** + * A test started. + */ + function startTest(test:Test):void; + } + } Index: /as3/Syndication/trunk/tests/org/libspark/asunit/framework/AS3UnitTestCaseFacade.as =================================================================== --- /as3/Syndication/trunk/tests/org/libspark/asunit/framework/AS3UnitTestCaseFacade.as (リビジョン 952) +++ /as3/Syndication/trunk/tests/org/libspark/asunit/framework/AS3UnitTestCaseFacade.as (リビジョン 952) @@ -0,0 +1,51 @@ +/* + * Copyright(c) 2006 the Spark project. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, + * either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + */ + +package org.libspark.asunit.framework +{ + import org.libspark.as3unit.runner.Description; + import flash.errors.IllegalOperationError; + + public class AS3UnitTestCaseFacade implements Test + { + private var fDescription:Description; + + public function AS3UnitTestCaseFacade(description:Description) + { + fDescription = description; + } + + public function toString():String + { + return description.toString(); + } + + public function countTestCases():int + { + return 1; + } + + public function run(result:TestResult):void + { + throw new IllegalOperationError('This test stub created only for informational purposes.'); + } + + public function get description():Description + { + return fDescription; + } + } +} Index: /as3/Syndication/trunk/tests/org/libspark/asunit/framework/AssertionFailedError.as =================================================================== --- /as3/Syndication/trunk/tests/org/libspark/asunit/framework/AssertionFailedError.as (リビジョン 952) +++ /as3/Syndication/trunk/tests/org/libspark/asunit/framework/AssertionFailedError.as (リビジョン 952) @@ -0,0 +1,29 @@ +/* + * Copyright(c) 2006 the Spark project. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, + * either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + */ + + package org.libspark.asunit.framework + { + /** + * Thrown when an assertion failed. + */ + public class AssertionFailedError extends Error + { + public function AssertionFailedError(message:String="") + { + super(message); + } + } + } Index: /as3/Syndication/trunk/tests/org/libspark/asunit/framework/AS3UnitTestAdapter.as =================================================================== --- /as3/Syndication/trunk/tests/org/libspark/asunit/framework/AS3UnitTestAdapter.as (リビジョン 952) +++ /as3/Syndication/trunk/tests/org/libspark/asunit/framework/AS3UnitTestAdapter.as (リビジョン 952) @@ -0,0 +1,71 @@ +/* + * Copyright(c) 2006 the Spark project. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, + * either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + */ + +package org.libspark.asunit.framework +{ + import org.libspark.as3unit.runner.Description; + import org.libspark.as3unit.runner.Request; + import org.libspark.as3unit.runner.Runner; + + import flash.utils.getQualifiedClassName; + + public class AS3UnitTestAdapter implements Test + { + private var newTestClass:Class; + private var runner:Runner; + private var cache:AS3UnitTestAdapterCache; + + public function AS3UnitTestAdapter(newTestClass:Class, cache:AS3UnitTestAdapterCache=null) + { + if (cache == null) { + cache = AS3UnitTestAdapterCache.getDefault(); + } + this.cache = cache; + this.newTestClass = newTestClass; + runner = Request.aClass(newTestClass).getRunner(); + } + + public function countTestCases():int + { + return runner.testCount; + } + + public function run(result:TestResult):void + { + runner.run(cache.getNotifier(result, this)); + } + + public function get tests():Array + { + return cache.asTestList(description); + } + + public function get testClass():Class + { + return newTestClass; + } + + public function get description():Description + { + return runner.description; + } + + public function toString():String + { + return getQualifiedClassName(newTestClass); + } + } +} Index: /as3/Syndication/trunk/tests/org/libspark/asunit/framework/TestFailure.as =================================================================== --- /as3/Syndication/trunk/tests/org/libspark/asunit/framework/TestFailure.as (リビジョン 952) +++ /as3/Syndication/trunk/tests/org/libspark/asunit/framework/TestFailure.as (リビジョン 952) @@ -0,0 +1,81 @@ +/* + * Copyright(c) 2006 the Spark project. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, + * either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + */ + + package org.libspark.asunit.framework + { + /** + * A TestFailure collects a failed test together with + * the caught exception. + * @see TestResult + */ + public class TestFailure + { + protected var failedTest_:Test; + protected var thrownError_:Object; + + /** + * Constructs a TestFailure with the given test and exception. + */ + public function TestFailure(failedTest:Test, thrownError:Object) + { + failedTest_ = failedTest; + thrownError_ = thrownError; + } + + /** + * Gets the failed test. + */ + public function get failedTest():Test + { + return failedTest_; + } + + /** + * Gets the thrown exception. + */ + public function get thrownError():Object + { + return thrownError_; + } + + /** + * Returns a short description of the failure. + */ + public function toString():String + { + return (failedTest_ + ': ' + errorMessage); + } + + public function get trace():String + { + if (thrownError_ is Error) { + return thrownError_.getStackTrace(); + } + return ''; + } + public function get errorMessage():String + { + if (thrownError_ is Error) { + return thrownError_.message; + } + return ''; + } + public function get isFailure():Boolean + { + return thrownError_ is AssertionFailedError; + } + } + } Index: /as3/Syndication/trunk/tests/org/libspark/asunit/framework/TestSuite.as =================================================================== --- /as3/Syndication/trunk/tests/org/libspark/asunit/framework/TestSuite.as (リビジョン 952) +++ /as3/Syndication/trunk/tests/org/libspark/asunit/framework/TestSuite.as (リビジョン 952) @@ -0,0 +1,239 @@ +/* + * Copyright(c) 2006 the Spark project. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, + * either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + */ + + package org.libspark.asunit.framework + { + import flash.utils.describeType; + + /** + * A TestSuite is a Composite of Tests. + * It runs a collection of test cases. Here is an example using + * the dynamic test definition. + *
    + 	 * var suite:TestSuite = new TestSuite();
    + 	 * suite.addTest(new MathTest("testAdd"));
    + 	 * suite.addTest(new MathTest("testDivideByZero");
    + 	 * 
    + * Alternatively, a TestSuite can extract the tests to be run automatically. + * To do so you pass the class of your TestCase class to the + * TestSuite constructor. + *
    + 	 * var suite:TestSuite = new TestSuite(MathTest);
    + 	 * 
    + * This constructor creates a suite with all the methods + * starting with "test" that take no arguments. + * + * @see Test + */ + public class TestSuite implements Test + { + private var tests_:Array; + private var name_:String; + + /** + * Constructs a TestSuite from the given class with the given name. + * Adds all the methods starting with "test" as test cases to the suite. + */ + public function TestSuite(theClass:Class=null, name:String=null) + { + tests_ = new Array(); + + if (theClass != null) { + var names:Object = new Object(); + for each (var method:XML in describeType(theClass).factory.method) { + addTestMethod(method, names, theClass); + } + if (tests_.length == 0) { + addTest(warning("No tests found in " + theClass)); + } + } + if (name != null) { + this.name = name;; + } + } + + private function isTestMethod(method:XML):Boolean + { + var name:String = String(method.@name); + var parameters:XMLList = method.parameter; + var returnType:String = String(method.@returnType); + + return parameters.length() == 0 && name.substr(0, 4) == "test" && returnType == "void"; + } + + private function addTestMethod(method:XML, names:Object, theClass:Class):void + { + var name:String = String(method.@name); + if (name in names) { + return; + } + if (!isTestMethod(method)) { + return; + } + names[name] = true; + addTest(createTest(theClass, name)); + } + + static public function createTest(theClass:Class, name:String):Test + { + var constructor:XMLList = describeType(theClass).factory.constructor; + var test:Test; + + try { + if (constructor == null || (constructor.parameter).length() == 0) { + test = new theClass(); + if (test is TestCase) { + TestCase(test).setName(name); + } + } + else { + test = new theClass(name); + } + } + catch (e:TypeError) { + return warning("Cannot instantiate test case: " + name + " (" + e.getStackTrace() + ")"); + } + + return test; + } + + /** + * Adds a test to the suite. + */ + public function addTest(test:Test):void + { + tests_.push(test); + } + + /** + * Adds the tests from the given class to the suite. + */ + public function addTestSuite(theClass:Class):void + { + addTest(new TestSuite(theClass)); + } + + /** + * Counts the number of test cases that will be run by this test. + */ + public function countTestCases():int + { + var total:uint = 0; + var tests_:Array = tests; + var count:uint = tests_.length; + for (var i:uint = 0; i < count; ++i) { + total += Test(tests_[i]).countTestCases(); + } + return total; + } + + /** + * Runs the tests and collects their result in a TestResult. + */ + public function run(result:TestResult):void + { + var tests_:Array = tests; + var count:uint = tests_.length; + for (var i:uint = 0; i < count; ++i) { + if (result.shouldStop) { + break; + } + runTest(Test(tests_[i]), result); + } + } + + public function runTest(test:Test, result:TestResult):void + { + test.run(result); + } + + /** + * Returns the test at the given index. + */ + public function testAt(index:uint):Test + { + return Test(tests_[index]); + } + + /** + * Returns the number of tests in this suite. + */ + public function get testCount():uint + { + return tests_.length; + } + + /** + * Returns the tests as an array. + */ + public function get tests():Array + { + return tests_; + } + + public function toString():String + { + if (name != null) { + return name; + } + return super.toString(); + } + + /** + * Sets the name of the suite. + * @param name The name to set + */ + public function set name(name:String):void + { + name_ = name; + } + + /** + * Returns the name of the suite. Not all + * tes tsuites have a name and this method + * can return null. + */ + public function get name():String + { + return name_; + } + + /** + * Returns the which will fail and log a warning message. + */ + private static function warning(message:String):Test + { + return new Warning(message); + } + } + } + + import org.libspark.asunit.framework.TestCase; + + class Warning extends TestCase + { + private var message:String; + + public function Warning(message:String) + { + super("warning"); + this.message = message; + } + protected override function runTest():void + { + fail(message); + } + } Index: /as3/Syndication/trunk/tests/org/libspark/asunit/framework/AS3UnitTestAdapterCache.as =================================================================== --- /as3/Syndication/trunk/tests/org/libspark/asunit/framework/AS3UnitTestAdapterCache.as (リビジョン 952) +++ /as3/Syndication/trunk/tests/org/libspark/asunit/framework/AS3UnitTestAdapterCache.as (リビジョン 952) @@ -0,0 +1,138 @@ +/* + * Copyright(c) 2006 the Spark project. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, + * either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + */ + +package org.libspark.asunit.framework +{ + import org.libspark.as3unit.runner.Description; + import org.libspark.as3unit.runner.notification.RunListener; + import org.libspark.as3unit.runner.notification.RunNotifier; + import org.libspark.as3unit.runner.notification.Failure; + import org.libspark.asunit.framework.AS3UnitTestAdapterCache; + + public class AS3UnitTestAdapterCache + { + private static var instance:AS3UnitTestAdapterCache = new AS3UnitTestAdapterCache(); + + private var map:Object; + + public function AS3UnitTestAdapterCache() + { + map = new Object(); + } + + public function put(description:Description, test:Test):void + { + map[description.displayName] = test; + } + + public function get(description:Description):Test + { + return map[description.displayName]; + } + + public function containsKey(description:Description):Boolean + { + return (description.displayName in map); + } + + public static function getDefault():AS3UnitTestAdapterCache + { + return instance; + } + + public function asTest(description:Description):Test + { + if (description.isSuite) { + return createTest(description); + } + else { + if (!containsKey(description)) { + put(description, createTest(description)); + } + return get(description); + } + } + + internal function createTest(description:Description):Test + { + if (description.isTest) { + return new AS3UnitTestCaseFacade(description); + } + else { + var suite:TestSuite = new TestSuite(null, description.displayName); + for each (var child:Description in description.children) { + suite.addTest(asTest(child)); + } + return suite; + } + } + + public function getNotifier(result:TestResult, adapter:AS3UnitTestAdapter):RunNotifier + { + var notifier:RunNotifier = new RunNotifier(); + notifier.addListener(new RunListenerAdapter(this, result)); + return notifier; + } + + public function asTestList(description:Description):Array + { + if (description.isTest) { + return [asTest(description)]; + } + else { + var returnThis:Array = new Array(); + for each (var child:Description in description.children) { + returnThis.push(asTest(child)); + } + return returnThis; + } + } + } +} + +import org.libspark.asunit.framework.TestResult; +import org.libspark.asunit.framework.AS3UnitTestAdapterCache; +import org.libspark.as3unit.runner.notification.RunListener; +import org.libspark.as3unit.runner.notification.Failure; +import org.libspark.as3unit.runner.Description; + +class RunListenerAdapter extends RunListener +{ + private var adapterCache:AS3UnitTestAdapterCache; + private var result:TestResult; + + public function RunListenerAdapter(adapterCache:AS3UnitTestAdapterCache, + result:TestResult) + { + this.adapterCache = adapterCache; + this.result = result + } + + public override function testFailure(failure:Failure):void + { + result.addError(adapterCache.asTest(failure.description), failure.exception); + } + + public override function testFinished(description:Description):void + { + result.endTest(adapterCache.asTest(description)); + } + + public override function testStarted(description:Description):void + { + result.startTest(adapterCache.asTest(description)); + } +} Index: /as3/Syndication/trunk/tests/org/libspark/asunit/framework/TestCase.as =================================================================== --- /as3/Syndication/trunk/tests/org/libspark/asunit/framework/TestCase.as (リビジョン 952) +++ /as3/Syndication/trunk/tests/org/libspark/asunit/framework/TestCase.as (リビジョン 952) @@ -0,0 +1,203 @@ +/* + * Copyright(c) 2006 the Spark project. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, + * either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + */ + +package org.libspark.asunit.framework +{ + import flash.utils.getQualifiedClassName; + + /** + * A test case defines the fixture to run multiple tests. To define a test case + *
      + *
    1. implement a subclass of TestCase
    2. + *
    3. define instance variables that store the state of the fixture
    4. + *
    5. initialize the fixture state by overriding setUp
    6. + *
    7. clean-up after a test by overriding tearDown
    8. + *
    + * Each test runs in its own fixture so there + * can be no side effects among test runs. + * Here is an example: + *
    +	 * public class MathTest extends TestCase
    +	 * {
    +	 *     protected var fValue1:Number;
    +	 *     protected var fValue2:Number;
    +	 * 
    +	 *     protected override function setUp():void
    +	 *     {
    +	 *         fValue1 = 2.0;
    +	 *         fValue2 = 3.0;
    +	 *     }
    +	 * }
    +	 * 
    + * + * For each test implement a method which interacts + * with the fixture. Verify the expected results with assertions specified + * by calling assertTrue with a boolean. + *
    +	 *     public function testAdd():void
    +	 *     {
    +	 *          var result:Number = fValue1 + fValue2;
    +	 *          assertTrue(result == 5.0);
    +	 *      }
    +	 * 
    + * Once the methods are defined you can run them. The framework supports + * both a static type safe and more dynamic way to run a test. + * In the static way you override the runTest method and define the + * method to be invoked. + * The dynamic way uses reflection to implement runTest. It dynamically finds + * and invokes a method. + * In this case the name of the test case has to correspond to the test method + * to be run. + *
    +	 * var test:TestCase = new MathTest("testAdd");
    +	 * test.run();
    +	 * 
    + * The tests to be run can be collected into a TestSuite. ASUnit provides + * different test runners which can run a test suite and collect the results. + * A test runner either expects a static method suite as the entry + * point to get a test to run or it will extract the suite automatically. + *
    +	 * static public function suite():Test
    +	 * {
    +	 *     suite.addTest(new MathTest("testAdd"));
    +	 *     suite.addTest(new MathTest("testDivideByZero"));
    +	 *     return suite;
    +	 * }
    +	 * 
    + * @see TestResult + * @see TestSuite + */ + public class TestCase extends Assert implements Test + { + /** + * the name of test case + */ + private var name:String; + + /** + * Construct a test case with the five name. + */ + public function TestCase(name:String=null) + { + this.name = name; + } + + /** + * Counts the number of test cases executed by run method. + */ + public function countTestCases():int + { + return 1; + } + + /** + * A convenience method to run this test, collecting the results with a + * default TestResult object. + * + * @see TestResult + */ + public function runDefault():TestResult + { + var result:TestResult = new TestResult(); + run(result); + return result; + } + + /** + * Runs the test case and collects the results in TestResult. + */ + public function run(result:TestResult):void + { + result.run(this); + } + + /** + * Runs the bare test sequence. + */ + public function runBare():void + { + setUp(); + try { + runTest(); + } + finally { + tearDown(); + } + } + + /** + * Override to run the test and assert its state. + */ + protected function runTest():void + { + assertNotNull(name); + + try { + if (this[name] is Function) { + this[name](); + } + else { + fail(name + " is not method."); + } + } + catch (e:ReferenceError) { + fail('Method "' + name + '" not found'); + } + } + + /** + * Sets up the fixture, for example, open a network connection. + * This method is called before a test is executed. + */ + protected function setUp():void + { + } + + /** + * Tears down the fixture, for example, close a network connection. + * This method is called after a test is executed. + */ + protected function tearDown():void + { + } + + /** + * Returns a string representation of the test case. + */ + public function toString():String + { + return getName() + '(' + getQualifiedClassName(this) + ')'; + } + + /** + * Gets the name of a TestCase + * @return returns a String + */ + public function getName():String + { + return name; + } + + /** + * Sets the name of a TestCase + * @param name The name to set + */ + public function setName(name:String):void + { + this.name = name; + } + } +} Index: /as3/Syndication/trunk/tests/org/libspark/syndication/RSSFeedTests.as =================================================================== --- /as3/Syndication/trunk/tests/org/libspark/syndication/RSSFeedTests.as (リビジョン 952) +++ /as3/Syndication/trunk/tests/org/libspark/syndication/RSSFeedTests.as (リビジョン 952) @@ -0,0 +1,76 @@ +package org.libspark.syndication +{ + import flash.events.Event; + import flash.net.URLLoader; + import flash.net.URLRequest; + import org.libspark.as3unit.after; + import org.libspark.as3unit.before; + import org.libspark.as3unit.test; + import org.libspark.as3unit.assert.*; + + import org.libspark.syndication.IFeed; + import org.libspark.syndication.RSSFeed; + import org.libspark.syndication.RSSFeedEntry; + + use namespace after; + use namespace before; + use namespace test; + + /** + * RSSFeed's test class. + */ + public class RSSFeedTests + { + /** + * check title. + */ + test function title():void + { + var loader:URLLoader = new URLLoader(new URLRequest("xml/berian-rss.xml")); + loader.addEventListener(Event.COMPLETE, async(function (evt:Event):void + { + var result:XML = XML(evt.target.data); + var feed:IFeed = new RSSFeed(result); + + assertEquals(feed.title, 'belog'); + + }, 200)); + } + + /** + * check link. + */ + test function link():void + { + var loader:URLLoader = new URLLoader(new URLRequest("xml/berian-rss.xml")); + loader.addEventListener(Event.COMPLETE, async(function (evt:Event):void + { + var result:XML = XML(evt.target.data); + var feed:IFeed = new RSSFeed(result); + + assertEquals(feed.link, 'http://d.hatena.ne.jp/berian/'); + + }, 200)); + } + + /** + * check entries. + */ + test function entries():void + { + var loader:URLLoader = new URLLoader(new URLRequest("xml/berian-rss.xml")); + loader.addEventListener(Event.COMPLETE, async(function (evt:Event):void + { + var result:XML = XML(evt.target.data); + var feed:IFeed = new RSSFeed(result); + + assertEquals(feed.entries.length, 5); + for each (var e:* in feed.entries) + { + assertTrue(e is RSSFeedEntry); + } + + }, 200)); + } + } +} Index: /as3/Syndication/trunk/tests/org/libspark/syndication/RSS2FeedTests.as =================================================================== --- /as3/Syndication/trunk/tests/org/libspark/syndication/RSS2FeedTests.as (リビジョン 952) +++ /as3/Syndication/trunk/tests/org/libspark/syndication/RSS2FeedTests.as (リビジョン 952) @@ -0,0 +1,76 @@ +package org.libspark.syndication +{ + import flash.events.Event; + import flash.net.URLLoader; + import flash.net.URLRequest; + import org.libspark.as3unit.after; + import org.libspark.as3unit.before; + import org.libspark.as3unit.test; + import org.libspark.as3unit.assert.*; + + import org.libspark.syndication.IFeed; + import org.libspark.syndication.RSS2Feed; + import org.libspark.syndication.RSS2FeedEntry; + + use namespace after; + use namespace before; + use namespace test; + + /** + * RSS2Feed's test class. + */ + public class RSS2FeedTests + { + /** + * check title. + */ + test function title():void + { + var loader:URLLoader = new URLLoader(new URLRequest("xml/berian-rss2.xml")); + loader.addEventListener(Event.COMPLETE, async(function (evt:Event):void + { + var result:XML = XML(evt.target.data); + var feed:IFeed = new RSS2Feed(result); + + assertEquals(feed.title, 'belog'); + + }, 200)); + } + + /** + * check link. + */ + test function link():void + { + var loader:URLLoader = new URLLoader(new URLRequest("xml/berian-rss2.xml")); + loader.addEventListener(Event.COMPLETE, async(function (evt:Event):void + { + var result:XML = XML(evt.target.data); + var feed:IFeed = new RSS2Feed(result); + + assertEquals(feed.link, 'http://d.hatena.ne.jp/berian/'); + + }, 200)); + } + + /** + * check entries. + */ + test function entries():void + { + var loader:URLLoader = new URLLoader(new URLRequest("xml/berian-rss2.xml")); + loader.addEventListener(Event.COMPLETE, async(function (evt:Event):void + { + var result:XML = XML(evt.target.data); + var feed:IFeed = new RSS2Feed(result); + + assertEquals(feed.entries.length, 5); + for each (var e:* in feed.entries) + { + assertTrue(e is RSS2FeedEntry); + } + + }, 200)); + } + } +} Index: /as3/Syndication/trunk/tests/org/libspark/syndication/RSS2FeedEntryTests.as =================================================================== --- /as3/Syndication/trunk/tests/org/libspark/syndication/RSS2FeedEntryTests.as (リビジョン 952) +++ /as3/Syndication/trunk/tests/org/libspark/syndication/RSS2FeedEntryTests.as (リビジョン 952) @@ -0,0 +1,133 @@ +package org.libspark.syndication +{ + import flash.events.Event; + import flash.net.URLLoader; + import flash.net.URLRequest; + import org.libspark.as3unit.after; + import org.libspark.as3unit.before; + import org.libspark.as3unit.test; + import org.libspark.as3unit.assert.*; + + import org.libspark.syndication.IFeed; + import org.libspark.syndication.IFeedEntry; + import org.libspark.syndication.RSS2Feed; + import org.libspark.syndication.RSS2FeedEntry; + + use namespace after; + use namespace before; + use namespace test; + + /** + * + */ + public class RSS2FeedEntryTests + { + public static const FeedClass:Class = RSS2Feed; + public static const FeedEntryClass:Class = RSS2FeedEntry; + + /** + * check author. (not required) + */ + test function author():void + { + var loader:URLLoader = new URLLoader(new URLRequest("xml/cellfusion-rss2.xml")); + loader.addEventListener(Event.COMPLETE, async(function (evt:Event):void + { + var result:XML = XML(evt.target.data); + var feed:IFeed = new FeedClass(result); + var entry:IFeedEntry = feed.entries[0]; + + assertEquals(entry.author, ''); + + }, 200)); + } + + /** + * check title. + */ + test function title():void + { + var loader:URLLoader = new URLLoader(new URLRequest("xml/cellfusion-rss2.xml")); + loader.addEventListener(Event.COMPLETE, async(function (evt:Event):void + { + var result:XML = XML(evt.target.data); + var feed:IFeed = new FeedClass(result); + var entry:IFeedEntry = feed.entries[0]; + + assertEquals(entry.title, '今さら「はて☆スタ」つけた'); + + }, 200)); + } + + /** + * check link. + */ + test function link():void + { + var loader:URLLoader = new URLLoader(new URLRequest("xml/cellfusion-rss2.xml")); + loader.addEventListener(Event.COMPLETE, async(function (evt:Event):void + { + var result:XML = XML(evt.target.data); + var feed:IFeed = new FeedClass(result); + var entry:IFeedEntry = feed.entries[0]; + + assertEquals(entry.link, 'http://blog.cellfusion.jp/archives/634/'); + + }, 200)); + } + + /** + * check description. + */ + test function description():void + { + var loader:URLLoader = new URLLoader(new URLRequest("xml/cellfusion-rss2.xml")); + loader.addEventListener(Event.COMPLETE, async(function (evt:Event):void + { + var result:XML = XML(evt.target.data); + var feed:IFeed = new FeedClass(result); + var entry:IFeedEntry = feed.entries[0]; + + assertEquals(entry.description, + '

    記事に対しての反応とかを見たかったから、今さらだけど はてなスター つけてみた。

    '); + + }, 200)); + } + + /** + * check published. + */ + test function published():void + { + var loader:URLLoader = new URLLoader(new URLRequest("xml/cellfusion-rss2.xml")); + loader.addEventListener(Event.COMPLETE, async(function (evt:Event):void + { + var result:XML = XML(evt.target.data); + var feed:IFeed = new FeedClass(result); + var entry:IFeedEntry = feed.entries[0]; + var checked:Date = new Date('Sun Aug 10 21:13:41 GMT+0900 2008'); + + assertEquals(entry.published.getTime(), checked.getTime()); + + }, 200)); + } + + /** + * check categories. + */ + test function categories():void + { + var loader:URLLoader = new URLLoader(new URLRequest("xml/cellfusion-rss2.xml")); + loader.addEventListener(Event.COMPLETE, async(function (evt:Event):void + { + var result:XML = XML(evt.target.data); + var feed:IFeed = new FeedClass(result); + var entry:IFeedEntry = feed.entries[0]; + + assertEquals(entry.categories.length, 1); + assertEquals(entry.categories[0], 'Diary'); + + }, 200)); + } + } +} Index: /as3/Syndication/trunk/tests/org/libspark/syndication/FeedTests.as =================================================================== --- /as3/Syndication/trunk/tests/org/libspark/syndication/FeedTests.as (リビジョン 952) +++ /as3/Syndication/trunk/tests/org/libspark/syndication/FeedTests.as (リビジョン 952) @@ -0,0 +1,56 @@ +package org.libspark.syndication +{ + import org.libspark.as3unit.after; + import org.libspark.as3unit.before; + import org.libspark.as3unit.test; + import org.libspark.as3unit.assert.*; + + import org.libspark.syndication.Feed; + + use namespace after; + use namespace before; + use namespace test; + + public class FeedTests + { + test function title():void + { + + } + + test function link():void + { + + } + + test function entries():void + { + + } + + test function parse():void + { + + } + + /* + test function parseW3CDate():void + { + var parsed:Date; + var checked:Date = new Date('Thu Aug 07 2008 18:43:18 GMT+0900'); + + // tz = "Z" + parsed = Feed.parseW3CDate("2008-08-07T09:43:18Z"); + assertEquals(parsed.getTime(), checked.getTime()); + + // tz = +09:00 + parsed = Feed.parseW3CDate("2008-08-07T18:43:18+09:00"); + assertEquals(parsed.getTime(), checked.getTime()); + + // tz = -04:00 + parsed = Feed.parseW3CDate("2008-08-07T05:43:18-04:00"); + assertEquals(parsed.getTime(), checked.getTime()); + } + */ + } +} Index: /as3/Syndication/trunk/tests/org/libspark/syndication/AtomFeedTests.as =================================================================== --- /as3/Syndication/trunk/tests/org/libspark/syndication/AtomFeedTests.as (リビジョン 952) +++ /as3/Syndication/trunk/tests/org/libspark/syndication/AtomFeedTests.as (リビジョン 952) @@ -0,0 +1,76 @@ +package org.libspark.syndication +{ + import flash.events.Event; + import flash.net.URLLoader; + import flash.net.URLRequest; + import org.libspark.as3unit.after; + import org.libspark.as3unit.before; + import org.libspark.as3unit.test; + import org.libspark.as3unit.assert.*; + + import org.libspark.syndication.IFeed; + import org.libspark.syndication.AtomFeed; + import org.libspark.syndication.AtomFeedEntry; + + use namespace after; + use namespace before; + use namespace test; + + /** + * AtomFeed's test class. + */ + public class AtomFeedTests + { + /** + * check title. + */ + test function title():void + { + var loader:URLLoader = new URLLoader(new URLRequest("xml/cellfusion-atom.xml")); + loader.addEventListener(Event.COMPLETE, async(function (evt:Event):void + { + var result:XML = XML(evt.target.data); + var feed:IFeed = new AtomFeed(result); + + assertEquals(feed.title, 'cellfusion blog'); + + }, 200)); + } + + /** + * check link. + */ + test function link():void + { + var loader:URLLoader = new URLLoader(new URLRequest("xml/cellfusion-atom.xml")); + loader.addEventListener(Event.COMPLETE, async(function (evt:Event):void + { + var result:XML = XML(evt.target.data); + var feed:IFeed = new AtomFeed(result); + + assertEquals(feed.link, 'http://blog.cellfusion.jp/'); + + }, 200)); + } + + /** + * check entries. + */ + test function entries():void + { + var loader:URLLoader = new URLLoader(new URLRequest("xml/cellfusion-atom.xml")); + loader.addEventListener(Event.COMPLETE, async(function (evt:Event):void + { + var result:XML = XML(evt.target.data); + var feed:IFeed = new AtomFeed(result); + + assertEquals(feed.entries.length, 15); + for each (var e:* in feed.entries) + { + assertTrue(e is AtomFeedEntry); + } + + }, 200)); + } + } +} Index: /as3/Syndication/trunk/tests/org/libspark/syndication/AtomFeedEntryTests.as =================================================================== --- /as3/Syndication/trunk/tests/org/libspark/syndication/AtomFeedEntryTests.as (リビジョン 952) +++ /as3/Syndication/trunk/tests/org/libspark/syndication/AtomFeedEntryTests.as (リビジョン 952) @@ -0,0 +1,130 @@ +package org.libspark.syndication +{ + import flash.events.Event; + import flash.net.URLLoader; + import flash.net.URLRequest; + import org.libspark.as3unit.after; + import org.libspark.as3unit.before; + import org.libspark.as3unit.test; + import org.libspark.as3unit.assert.*; + + import org.libspark.syndication.IFeed; + import org.libspark.syndication.IFeedEntry; + import org.libspark.syndication.AtomFeed; + import org.libspark.syndication.AtomFeedEntry; + + use namespace after; + use namespace before; + use namespace test; + + /** + * + */ + public class AtomFeedEntryTests + { + /** + * check author. + */ + test function author():void + { + var loader:URLLoader = new URLLoader(new URLRequest("xml/cellfusion-atom.xml")); + loader.addEventListener(Event.COMPLETE, async(function (evt:Event):void + { + var result:XML = XML(evt.target.data); + var feed:IFeed = new AtomFeed(result); + var entry:IFeedEntry = feed.entries[0]; + + assertEquals(entry.author, 'Mk-10:cellfusion'); + + }, 200)); + } + + /** + * check title. + */ + test function title():void + { + var loader:URLLoader = new URLLoader(new URLRequest("xml/cellfusion-atom.xml")); + loader.addEventListener(Event.COMPLETE, async(function (evt:Event):void + { + var result:XML = XML(evt.target.data); + var feed:IFeed = new AtomFeed(result); + var entry:IFeedEntry = feed.entries[0]; + + assertEquals(entry.title, '今さら「はて☆スタ」つけた'); + + }, 200)); + } + + /** + * check link. + */ + test function link():void + { + var loader:URLLoader = new URLLoader(new URLRequest("xml/cellfusion-atom.xml")); + loader.addEventListener(Event.COMPLETE, async(function (evt:Event):void + { + var result:XML = XML(evt.target.data); + var feed:IFeed = new AtomFeed(result); + var entry:IFeedEntry = feed.entries[0]; + + assertEquals(entry.link, 'http://blog.cellfusion.jp/archives/634/'); + + }, 200)); + } + + /** + * check description. + */ + test function description():void + { + var loader:URLLoader = new URLLoader(new URLRequest("xml/cellfusion-atom.xml")); + loader.addEventListener(Event.COMPLETE, async(function (evt:Event):void + { + var result:XML = XML(evt.target.data); + var feed:IFeed = new AtomFeed(result); + var entry:IFeedEntry = feed.entries[0]; + + assertEquals(entry.description, + '

    記事に対しての反応とかを見たかったから、今さらだけど はてなスター つけてみた。

    '); + + }, 200)); + } + + /** + * check published. + */ + test function published():void + { + var loader:URLLoader = new URLLoader(new URLRequest("xml/cellfusion-atom.xml")); + loader.addEventListener(Event.COMPLETE, async(function (evt:Event):void + { + var result:XML = XML(evt.target.data); + var feed:IFeed = new AtomFeed(result); + var entry:IFeedEntry = feed.entries[0]; + var checked:Date = new Date('Sun Aug 10 21:13:41 GMT+0900 2008'); + + assertEquals(entry.published.getTime(), checked.getTime()); + + }, 200)); + } + + /** + * check categories. + */ + test function categories():void + { + var loader:URLLoader = new URLLoader(new URLRequest("xml/cellfusion-atom.xml")); + loader.addEventListener(Event.COMPLETE, async(function (evt:Event):void + { + var result:XML = XML(evt.target.data); + var feed:IFeed = new AtomFeed(result); + var entry:IFeedEntry = feed.entries[0]; + + assertEquals(entry.categories.length, 1); + assertEquals(entry.categories[0], 'Diary'); + + }, 200)); + } + } +} Index: /as3/Syndication/trunk/tests/org/libspark/syndication/AllTests.as =================================================================== --- /as3/Syndication/trunk/tests/org/libspark/syndication/AllTests.as (リビジョン 952) +++ /as3/Syndication/trunk/tests/org/libspark/syndication/AllTests.as (リビジョン 952) @@ -0,0 +1,20 @@ +package org.libspark.syndication +{ + import org.libspark.as3unit.runners.Suite; + + /** + * AllTest. + */ + public class AllTests + { + public static const RunWith:Class = Suite; + public static const SuiteClasses:Array = [ + FeedTests, + AtomFeedTests, + AtomFeedEntryTests, + RSSFeedTests, + RSS2FeedTests, + RSS2FeedEntryTests, + ]; + } +} Index: /as3/Syndication/trunk/tests/org/libspark/as3unit/assert/async.as =================================================================== --- /as3/Syndication/trunk/tests/org/libspark/as3unit/assert/async.as (リビジョン 952) +++ /as3/Syndication/trunk/tests/org/libspark/as3unit/assert/async.as (リビジョン 952) @@ -0,0 +1,42 @@ +/* + * Copyright(c) 2006 the Spark project. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, + * either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + */ + +package org.libspark.as3unit.assert +{ + import org.libspark.as3unit.inter.runners.AsyncHelper; + + /** + * Create an asynchronous assertion point. + * + * Example: + * // Test URLLoader loads text 'hello'. + * // It fails when one second (1000ms) passes without callback. + * urlLoader.addEventListener(Event.COMPLETE, async(function(e:Event):void + * { + * assertEquals('hello', urlLoader.data); + * }, 1000)); + * + * @param callback Callback function + * @param timeout Timeout[ms] + * @return Wrapped function + */ + public function async(callback:Function, timeout:uint = 5000):Function + { + var helper:AsyncHelper = new AsyncHelper(callback, timeout); + AsyncHelper.addAsyncHelper(helper); + return helper.async; + } +} Index: /as3/Syndication/trunk/tests/org/libspark/as3unit/assert/assertNotNull.as =================================================================== --- /as3/Syndication/trunk/tests/org/libspark/as3unit/assert/assertNotNull.as (リビジョン 952) +++ /as3/Syndication/trunk/tests/org/libspark/as3unit/assert/assertNotNull.as (リビジョン 952) @@ -0,0 +1,27 @@ +/* + * Copyright(c) 2006 the Spark project. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, + * either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + */ + +package org.libspark.as3unit.assert +{ + /** + * Asserts that an object isn't null. If it is + * an AssertionFailedError is thrown with the given message. + */ + public function assertNotNull(object:*, message:String=""):void + { + assertTrue(object != null, message); + } +} Index: /as3/Syndication/trunk/tests/org/libspark/as3unit/assert/ArrayComparsionFailure.as =================================================================== --- /as3/Syndication/trunk/tests/org/libspark/as3unit/assert/ArrayComparsionFailure.as (リビジョン 952) +++ /as3/Syndication/trunk/tests/org/libspark/as3unit/assert/ArrayComparsionFailure.as (リビジョン 952) @@ -0,0 +1,64 @@ +/* + * Copyright(c) 2006 the Spark project. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, + * either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + */ + +package org.libspark.as3unit.assert +{ + /** + * Thrown when two array elements differ. + */ + public class ArrayComparsionFailure extends AssertionFailedError + { + /** + * Construct a new ArrayComparisonFailure with an error text and the array's + * dimension that was not equal + * @param cause the exception that caused the array's content to fail the assertion test + * @param index the array position of the objects that are not equal. + */ + public function ArrayComparsionFailure(message:String, cause:AssertionFailedError, index:uint) + { + super(""); + this.msg = message; + this.cause = cause; + addDimension(index); + this.message = createMessage(message); + } + + private var indices:Array = []; + private var msg:String; + private var cause:AssertionFailedError; + + public function addDimension(index:uint):void + { + indices.unshift(index); + message = createMessage(msg); + } + + private function createMessage(message:String):String + { + var result:String = ""; + if (message != null) { + result += message; + } + result += "arrays first differed at element "; + for each (var each:uint in indices) { + result += "[" + each + "]"; + } + result += "; "; + result += cause.message; + return result; + } + } +} Index: /as3/Syndication/trunk/tests/org/libspark/as3unit/assert/failSame.as =================================================================== --- /as3/Syndication/trunk/tests/org/libspark/as3unit/assert/failSame.as (リビジョン 952) +++ /as3/Syndication/trunk/tests/org/libspark/as3unit/assert/failSame.as (リビジョン 952) @@ -0,0 +1,26 @@ +/* + * Copyright(c) 2006 the Spark project. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, + * either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + */ + +package org.libspark.as3unit.assert +{ + internal function failSame(message:String):void + { + if (message != '') { + message += ' '; + } + fail(message + 'expected not same'); + } +} Index: /as3/Syndication/trunk/tests/org/libspark/as3unit/assert/ComparsionFailure.as =================================================================== --- /as3/Syndication/trunk/tests/org/libspark/as3unit/assert/ComparsionFailure.as (リビジョン 952) +++ /as3/Syndication/trunk/tests/org/libspark/as3unit/assert/ComparsionFailure.as (リビジョン 952) @@ -0,0 +1,152 @@ +/* + * Copyright(c) 2006 the Spark project. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, + * either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + */ + +package org.libspark.as3unit.assert +{ + /** + * Thrown when an assertEquals(String, String) failes. + */ + public class ComparsionFailure extends AssertionFailedError + { + private static const MAX_CONTEXT_LENGTH:uint = 20; + + /** + * Constructs a comparison failure. + * @param message the identifying message or null + * @param expected the expected string value + * @param actual the actual string value + */ + public function ComparsionFailure(message:String, expected:String, actual:String) + { + super(createMessage(expected, actual, message)); + _expected = expected; + _actual = actual; + } + + private var _expected:String; + private var _actual:String; + + protected function createMessage(expected:String, actual:String, message:String):String + { + return new ComparsionCompactor(MAX_CONTEXT_LENGTH, expected, actual).compact(message); + } + + /** + * Returns the actual string value + * @return the actual string value + */ + public function get actual():String + { + return _actual; + } + + /** + * Returns the expected string value + * @return the expected string value + */ + public function get expected():String + { + return _expected; + } + } +} + +import org.libspark.as3unit.assert.format; + +class ComparsionCompactor +{ + private static const ELLIPSIS:String = "..."; + private static const DELTA_END:String = "]"; + private static const DELTA_START:String = "["; + + public function ComparsionCompactor(contextLength:uint, expected:String, actual:String) + { + this.contextLength = contextLength; + this.expected = expected; + this.actual = actual; + } + + private var contextLength:uint; + private var expected:String; + private var actual:String; + private var prefix:int; + private var suffix:int; + + public function compact(message:String):String + { + if (expected == null || actual == null || areStringsEqual()) { + return format(message, expected, actual); + } + + findCommonPrefix(); + findCommonSuffix(); + + var ex:String = compactString(expected); + var ac:String = compactString(actual); + return format(message, ex, ac); + } + + private function compactString(source:String):String + { + var result:String = DELTA_START + source.substring(prefix, source.length - suffix + 1) + DELTA_END; + if (prefix > 0) { + result = computeCommonPrefix() + result; + } + if (suffix > 0) { + result = result + computeCommonSuffix(); + } + return result; + } + + private function findCommonPrefix():void + { + prefix = 0; + var end:int = Math.min(expected.length, actual.length); + for (; prefix < end; ++prefix) { + if (expected.charAt(prefix) != actual.charAt(prefix)) { + break; + } + } + } + + private function findCommonSuffix():void + { + var expectedSuffix:int = expected.length - 1; + var actualSuffix:int = actual.length - 1; + for (; actualSuffix >= prefix && expectedSuffix >= prefix; --actualSuffix, --expectedSuffix) { + if (expected.charAt(expectedSuffix) != actual.charAt(actualSuffix)) { + break; + } + } + suffix = expected.length - expectedSuffix; + } + + private function computeCommonPrefix():String + { + return (prefix > contextLength ? ELLIPSIS : "") + expected.substring(Math.max(0, prefix - contextLength), prefix); + } + + private function computeCommonSuffix():String + { + var end:int = Math.min(expected.length - suffix + 1 + contextLength, expected.length); + return expected.substring(expected.length - suffix + 1, end) + (expected.length - suffix + 1 < expected.length - contextLength ? ELLIPSIS : ""); + } + + private function areStringsEqual():Boolean + { + return expected === actual; + } +} Index: /as3/Syndication/trunk/tests/org/libspark/as3unit/assert/AssertionFailedError.as =================================================================== --- /as3/Syndication/trunk/tests/org/libspark/as3unit/assert/AssertionFailedError.as (リビジョン 952) +++ /as3/Syndication/trunk/tests/org/libspark/as3unit/assert/AssertionFailedError.as (リビジョン 952) @@ -0,0 +1,29 @@ +/* + * Copyright(c) 2006 the Spark project. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, + * either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + */ + +package org.libspark.as3unit.assert +{ + /** + * Thrown when an assertion failed. + */ + public class AssertionFailedError extends Error + { + public function AssertionFailedError(message:String="") + { + super(message); + } + } +} Index: /as3/Syndication/trunk/tests/org/libspark/as3unit/assert/assertNotSame.as =================================================================== --- /as3/Syndication/trunk/tests/org/libspark/as3unit/assert/assertNotSame.as (リビジョン 952) +++ /as3/Syndication/trunk/tests/org/libspark/as3unit/assert/assertNotSame.as (リビジョン 952) @@ -0,0 +1,30 @@ +/* + * Copyright(c) 2006 the Spark project. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, + * either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + */ + +package org.libspark.as3unit.assert +{ + /** + * Asserts that two objects do not refer to the same object. If they are not + * an AssertionFailedError is thrown with the given message. + * This method uses Strict Equality Operator (===) for comparation. + */ + public function assertNotSame(expected:*, actual:*, message:String=""):void + { + if (expected === actual) { + failSame(message); + } + } +} Index: /as3/Syndication/trunk/tests/org/libspark/as3unit/assert/format.as =================================================================== --- /as3/Syndication/trunk/tests/org/libspark/as3unit/assert/format.as (リビジョン 952) +++ /as3/Syndication/trunk/tests/org/libspark/as3unit/assert/format.as (リビジョン 952) @@ -0,0 +1,36 @@ +/* + * Copyright(c) 2006 the Spark project. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, + * either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + */ + +package org.libspark.as3unit.assert +{ + import flash.utils.getQualifiedClassName; + + public function format(message:String, expected:Object, actual:Object):String + { + var formatted:String = ""; + if (message != null && message != "") { + formatted = message + " "; + } + var expectedString:String = String(expected); + var actualString:String = String(actual); + if (expectedString == actualString) { + return formatted + "expected: " + getQualifiedClassName(expected) + "<" + expectedString + "> but was: " + getQualifiedClassName(actual) + "<" + actualString + ">"; + } + else { + return formatted + "expected:<" + expectedString + "> but was:<" + actualString + ">"; + } + } +} Index: /as3/Syndication/trunk/tests/org/libspark/as3unit/assert/assertNull.as =================================================================== --- /as3/Syndication/trunk/tests/org/libspark/as3unit/assert/assertNull.as (リビジョン 952) +++ /as3/Syndication/trunk/tests/org/libspark/as3unit/assert/assertNull.as (リビジョン 952) @@ -0,0 +1,27 @@ +/* + * Copyright(c) 2006 the Spark project. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, + * either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + */ + +package org.libspark.as3unit.assert +{ + /** + * Asserts that an object is null. If it is not + * an AssertionFailedError is thrown with the given message. + */ + public function assertNull(object:*, message:String=""):void + { + assertTrue(object == null, message); + } +} Index: /as3/Syndication/trunk/tests/org/libspark/as3unit/assert/assertByteArrayEquals.as =================================================================== --- /as3/Syndication/trunk/tests/org/libspark/as3unit/assert/assertByteArrayEquals.as (リビジョン 952) +++ /as3/Syndication/trunk/tests/org/libspark/as3unit/assert/assertByteArrayEquals.as (リビジョン 952) @@ -0,0 +1,57 @@ +/* + * Copyright(c) 2006 the Spark project. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, + * either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + */ + +package org.libspark.as3unit.assert +{ + import flash.utils.ByteArray; + + /** + * Asserts that two ByteArrays are equal. If they are not + * an AssertionFailedError is thrown with the given message. + */ + public function assertByteArrayEquals(expected:ByteArray, actual:ByteArray, message:String=""):void + { + if (expected == null && actual == null) { + return; + } + if (expected != null && (expected.length == actual.length)) { + var len:uint = expected.length; + var index:uint = 0; + for (; index < len; ++index) { + if (actual[index] != expected[index]) { + break; + } + } + if (index == len) { + return; + } + } + failNotEquals(byteArray2HexString(expected), byteArray2HexString(actual), message); + } +} + +import flash.utils.ByteArray; + +function byteArray2HexString(bytes:ByteArray):String +{ + var hex:String = "0123456789abcdef"; + var hexString:String = "0x"; + for (var i:uint = 0; i < bytes.length; ++i) { + var n:uint = bytes[i]; + hexString += hex.charAt((n >> 4) & 0xf) + hex.charAt(n & 0xf); + } + return hexString; +} Index: /as3/Syndication/trunk/tests/org/libspark/as3unit/assert/assertTrue.as =================================================================== --- /as3/Syndication/trunk/tests/org/libspark/as3unit/assert/assertTrue.as (リビジョン 952) +++ /as3/Syndication/trunk/tests/org/libspark/as3unit/assert/assertTrue.as (リビジョン 952) @@ -0,0 +1,29 @@ +/* + * Copyright(c) 2006 the Spark project. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, + * either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + */ + +package org.libspark.as3unit.assert +{ + /** + * Asserts that a condition is true. If it isn't it throws + * an AssertionFailedError with the given message. + */ + public function assertTrue(condition:Boolean, message:String=""):void + { + if (!condition) { + fail(message); + } + } +} Index: /as3/Syndication/trunk/tests/org/libspark/as3unit/assert/failNotSame.as =================================================================== --- /as3/Syndication/trunk/tests/org/libspark/as3unit/assert/failNotSame.as (リビジョン 952) +++ /as3/Syndication/trunk/tests/org/libspark/as3unit/assert/failNotSame.as (リビジョン 952) @@ -0,0 +1,26 @@ +/* + * Copyright(c) 2006 the Spark project. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, + * either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + */ + +package org.libspark.as3unit.assert +{ + internal function failNotSame(expected:*, actual:*, message:String):void + { + if (message != '') { + message += ' '; + } + fail(message + 'expected same:<' + expected + '> was not:<' + actual + '>'); + } +} Index: /as3/Syndication/trunk/tests/org/libspark/as3unit/assert/failNotEquals.as =================================================================== --- /as3/Syndication/trunk/tests/org/libspark/as3unit/assert/failNotEquals.as (リビジョン 952) +++ /as3/Syndication/trunk/tests/org/libspark/as3unit/assert/failNotEquals.as (リビジョン 952) @@ -0,0 +1,23 @@ +/* + * Copyright(c) 2006 the Spark project. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, + * either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + */ + +package org.libspark.as3unit.assert +{ + internal function failNotEquals(expected:*, actual:*, message:String):void + { + fail(format(message, expected, actual)); + } +} Index: /as3/Syndication/trunk/tests/org/libspark/as3unit/assert/assertSame.as =================================================================== --- /as3/Syndication/trunk/tests/org/libspark/as3unit/assert/assertSame.as (リビジョン 952) +++ /as3/Syndication/trunk/tests/org/libspark/as3unit/assert/assertSame.as (リビジョン 952) @@ -0,0 +1,31 @@ +/* + * Copyright(c) 2006 the Spark project. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, + * either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + */ + +package org.libspark.as3unit.assert +{ + /** + * Asserts that two objects refer to the same object. If they are not + * an AssertionFailedError is thrown with the given message. + * This method uses Strict Equality Operator (===) for comparation. + */ + public function assertSame(expected:*, actual:*, message:String=""):void + { + if (expected === actual) { + return; + } + failNotSame(expected, actual, message); + } +} Index: /as3/Syndication/trunk/tests/org/libspark/as3unit/assert/fail.as =================================================================== --- /as3/Syndication/trunk/tests/org/libspark/as3unit/assert/fail.as (リビジョン 952) +++ /as3/Syndication/trunk/tests/org/libspark/as3unit/assert/fail.as (リビジョン 952) @@ -0,0 +1,26 @@ +/* + * Copyright(c) 2006 the Spark project. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, + * either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + */ + +package org.libspark.as3unit.assert +{ + /** + * Fails a test with the given message. + */ + public function fail(message:String = ""):void + { + throw new AssertionFailedError(message == null ? "" : message); + } +} Index: /as3/Syndication/trunk/tests/org/libspark/as3unit/assert/assertArrayEquals.as =================================================================== --- /as3/Syndication/trunk/tests/org/libspark/as3unit/assert/assertArrayEquals.as (リビジョン 952) +++ /as3/Syndication/trunk/tests/org/libspark/as3unit/assert/assertArrayEquals.as (リビジョン 952) @@ -0,0 +1,65 @@ +/* + * Copyright(c) 2006 the Spark project. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, + * either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + */ + +package org.libspark.as3unit.assert +{ + /** + * Asserts that two arrays are equal. If they are not + * an AssertionFailedError is thrown with the given message. + */ + public function assertArrayEquals(expected:Array, actual:Array, message:String = ""):void + { + if (expected == actual) { + return; + } + + var header:String = (message == null || message == "") ? "" : message + ": "; + + if (expected == null) { + fail(header + "expected array was null"); + } + if (actual == null) { + fail(header + "actual array was null"); + } + var actualLength:uint = actual.length; + var expectedLength:uint = expected.length; + if (actualLength != expectedLength) { + fail(header + "array lengths differed, expected.length=" + expectedLength + " actual.length=" + actualLength); + } + + for (var i:uint = 0; i < expectedLength; ++i) { + var expectedObject:* = expected[i]; + var actualObject:* = actual[i]; + if (expectedObject is Array && actualObject is Array) { + try { + assertArrayEquals(expectedObject, actualObject, message); + } + catch (e1:ArrayComparsionFailure) { + e1.addDimension(i); + throw e1; + } + } + else { + try { + assertEquals(expectedObject, actualObject); + } + catch (e2:AssertionFailedError) { + throw new ArrayComparsionFailure(header, e2, i); + } + } + } + } +} Index: /as3/Syndication/trunk/tests/org/libspark/as3unit/assert/assertFalse.as =================================================================== --- /as3/Syndication/trunk/tests/org/libspark/as3unit/assert/assertFalse.as (リビジョン 952) +++ /as3/Syndication/trunk/tests/org/libspark/as3unit/assert/assertFalse.as (リビジョン 952) @@ -0,0 +1,27 @@ +/* + * Copyright(c) 2006 the Spark project. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, + * either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + */ + +package org.libspark.as3unit.assert +{ + /** + * Asserts that a condition is false. If it isn't it throws + * an AssertionFailedError with the given message. + */ + public function assertFalse(condition:Boolean, message:String=""):void + { + assertTrue(!condition, message); + } +} Index: /as3/Syndication/trunk/tests/org/libspark/as3unit/assert/assertEquals.as =================================================================== --- /as3/Syndication/trunk/tests/org/libspark/as3unit/assert/assertEquals.as (リビジョン 952) +++ /as3/Syndication/trunk/tests/org/libspark/as3unit/assert/assertEquals.as (リビジョン 952) @@ -0,0 +1,51 @@ +/* + * Copyright(c) 2006 the Spark project. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, + * either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + */ + +package org.libspark.as3unit.assert +{ + import flash.utils.ByteArray; + + /** + * Asserts that two objects are equal. If they are not + * an AssertionFailedError is thrown with the given message. + */ + public function assertEquals(expected:*, actual:*, message:String = ""):void + { + if (expected == null && actual == null) { + return; + } + if (expected != null) { + if (expected == actual) { + return; + } + if (expected is Array && actual is Array) { + assertArrayEquals(expected, actual, message); + return; + } + if (expected is ByteArray && actual is ByteArray) { + assertByteArrayEquals(expected, actual, message); + return; + } + if ('equals' in expected && expected.equals(actual)) { + return; + } + } + if (expected is String && actual is String) { + throw new ComparsionFailure(message, expected, actual); + } + failNotEquals(expected, actual, message); + } +} Index: /as3/Syndication/trunk/tests/org/libspark/as3unit/inter/requests/ClassRequest.as =================================================================== --- /as3/Syndication/trunk/tests/org/libspark/as3unit/inter/requests/ClassRequest.as (リビジョン 952) +++ /as3/Syndication/trunk/tests/org/libspark/as3unit/inter/requests/ClassRequest.as (リビジョン 952) @@ -0,0 +1,96 @@ +/* + * Copyright(c) 2006 the Spark project. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, + * either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + */ + +package org.libspark.as3unit.inter.requests +{ + import org.libspark.as3unit.ignore; + import org.libspark.as3unit.inter.runners.InitializationError; + import org.libspark.as3unit.inter.runners.OldTestClassRunner; + import org.libspark.as3unit.inter.runners.TestClassRunner; + import org.libspark.as3unit.runner.Request; + import org.libspark.as3unit.runner.Runner; + import org.libspark.as3unit.runners.AllTests; + import org.libspark.asunit.framework.TestCase; + + import flash.utils.describeType; + import flash.utils.getQualifiedClassName; + + public class ClassRequest extends Request + { + private var testClass:Class; + private var canUseSuiteMethod:Boolean; + + public function ClassRequest(testClass:Class, canUseSuiteMethod:Boolean = true) + { + this.testClass = testClass; + this.canUseSuiteMethod = canUseSuiteMethod; + } + + public override function getRunner():Runner + { + return buildRunner(getRunnerClass(testClass)); + } + + public function buildRunner(runnerClass:Class):Runner + { + try { + return new runnerClass(testClass); + } + catch (e:Error) { + return Request.errorReport(testClass, e).getRunner(); + } + return null; + } + + internal function getRunnerClass(testClass:Class):Class + { + if ('Ignore' in testClass) { + return IgnoredClassRunner; + } + if ('RunWith' in testClass) { + return testClass.RunWith; + } + else if (hasSuiteMethod() && canUseSuiteMethod) { + return AllTests; + } + else if (isPre4Test(testClass)) { + return OldTestClassRunner; + } + else { + return TestClassRunner; + } + } + + public function hasSuiteMethod():Boolean + { + if ('suite' in testClass) { + return true; + } + return false; + } + + internal function isPre4Test(testClass:Class):Boolean + { + const type:String = getQualifiedClassName(TestCase); + for each (var ex:XML in describeType(testClass).factory.extendsClass) { + if (ex.@type == type) { + return true; + } + } + return false; + } + } +} Index: /as3/Syndication/trunk/tests/org/libspark/as3unit/inter/requests/FilterRequest.as =================================================================== --- /as3/Syndication/trunk/tests/org/libspark/as3unit/inter/requests/FilterRequest.as (リビジョン 952) +++ /as3/Syndication/trunk/tests/org/libspark/as3unit/inter/requests/FilterRequest.as (リビジョン 952) @@ -0,0 +1,49 @@ +/* + * Copyright(c) 2006 the Spark project. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, + * either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + */ + +package org.libspark.as3unit.inter.requests +{ + import org.libspark.as3unit.runner.Request; + import org.libspark.as3unit.runner.Runner; + import org.libspark.as3unit.runner.manipulation.Filter; + import org.libspark.as3unit.runner.manipulation.NoTestsRemainException; + + public class FilterRequest extends Request + { + private var request:Request; + private var filter:Filter; + + public function FilterRequest(classRequest:Request, filter:Filter) + { + request = classRequest; + this.filter = filter; + } + + public override function getRunner():Runner + { + try { + var runner:Runner = request.getRunner(); + filter.apply(runner); + return runner; + } + catch (e:NoTestsRemainException) { + return Request.errorReport(Filter, new Error('No tests found matching ' + + filter.describe + ' from ' + request)).getRunner(); + } + return null; + } + } +} Index: /as3/Syndication/trunk/tests/org/libspark/as3unit/inter/requests/SortingRequest.as =================================================================== --- /as3/Syndication/trunk/tests/org/libspark/as3unit/inter/requests/SortingRequest.as (リビジョン 952) +++ /as3/Syndication/trunk/tests/org/libspark/as3unit/inter/requests/SortingRequest.as (リビジョン 952) @@ -0,0 +1,43 @@ +/* + * Copyright(c) 2006 the Spark project. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, + * either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + */ + +package org.libspark.as3unit.inter.requests +{ + import org.libspark.as3unit.runner.Description; + import org.libspark.as3unit.runner.Request; + import org.libspark.as3unit.runner.Runner; + import org.libspark.as3unit.runner.manipulation.Sorter; + import org.libspark.as3unit.runner.manipulation.Comparator; + + public class SortingRequest extends Request + { + private var request:Request; + private var comparator:Comparator; + + public function SortingRequest(request:Request, comparator:Comparator) + { + this.request = request; + this.comparator = comparator; + } + + public override function getRunner():Runner + { + var runner:Runner = request.getRunner(); + new Sorter(comparator).apply(runner); + return runner; + } + } +} Index: /as3/Syndication/trunk/tests/org/libspark/as3unit/inter/requests/ClassesRequest.as =================================================================== --- /as3/Syndication/trunk/tests/org/libspark/as3unit/inter/requests/ClassesRequest.as (リビジョン 952) +++ /as3/Syndication/trunk/tests/org/libspark/as3unit/inter/requests/ClassesRequest.as (リビジョン 952) @@ -0,0 +1,46 @@ +/* + * Copyright(c) 2006 the Spark project. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, + * either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + */ + +package org.libspark.as3unit.inter.requests +{ + import org.libspark.as3unit.inter.runners.CompositeRunner; + import org.libspark.as3unit.runner.Request; + import org.libspark.as3unit.runner.Runner; + + public class ClassesRequest extends Request + { + private var classes:Array; + private var name:String; + + public function ClassesRequest(name:String, classes:Array) + { + this.classes = classes; + this.name = name; + } + + public override function getRunner():Runner + { + var runner:CompositeRunner = new CompositeRunner(name); + for each (var eachClass:Class in classes) { + var childRunner:Runner = Request.aClass(eachClass).getRunner(); + if (childRunner != null) { + runner.add(childRunner); + } + } + return runner; + } + } +} Index: /as3/Syndication/trunk/tests/org/libspark/as3unit/inter/requests/IgnoredClassRunner.as =================================================================== --- /as3/Syndication/trunk/tests/org/libspark/as3unit/inter/requests/IgnoredClassRunner.as (リビジョン 952) +++ /as3/Syndication/trunk/tests/org/libspark/as3unit/inter/requests/IgnoredClassRunner.as (リビジョン 952) @@ -0,0 +1,43 @@ +/* + * Copyright(c) 2006 the Spark project. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, + * either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + */ + +package org.libspark.as3unit.inter.requests +{ + import org.libspark.as3unit.runner.Description; + import org.libspark.as3unit.runner.Runner; + import org.libspark.as3unit.runner.notification.RunNotifier; + import flash.utils.getQualifiedClassName; + + public class IgnoredClassRunner extends Runner + { + public function IgnoredClassRunner(testClass:Class) + { + this.testClass = testClass; + } + + private var testClass:Class; + + public override function run(notifier:RunNotifier):void + { + notifier.fireTestIgnored(description); + } + + public override function get description():Description + { + return Description.createSuiteDescription(getQualifiedClassName(testClass)); + } + } +} Index: /as3/Syndication/trunk/tests/org/libspark/as3unit/inter/requests/ErrorReportingRequest.as =================================================================== --- /as3/Syndication/trunk/tests/org/libspark/as3unit/inter/requests/ErrorReportingRequest.as (リビジョン 952) +++ /as3/Syndication/trunk/tests/org/libspark/as3unit/inter/requests/ErrorReportingRequest.as (リビジョン 952) @@ -0,0 +1,59 @@ +/* + * Copyright(c) 2006 the Spark project. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, + * either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + */ + +package org.libspark.as3unit.inter.requests +{ + import org.libspark.as3unit.inter.runners.CompositeRunner; + import org.libspark.as3unit.inter.runners.ErrorReportingRunner; + import org.libspark.as3unit.inter.runners.InitializationError; + import org.libspark.as3unit.runner.Description; + import org.libspark.as3unit.runner.Request; + import org.libspark.as3unit.runner.Runner; + + import flash.utils.getQualifiedClassName; + + public class ErrorReportingRequest extends Request + { + private var fClass:Class; + private var fCause:Object; + + public function ErrorReportingRequest(klass:Class, cause:Object) + { + fClass = klass; + fCause = cause; + } + + public override function getRunner():Runner + { + var goofs:Array = getCauses(fCause); + var runner:CompositeRunner = new CompositeRunner(getQualifiedClassName(fClass)); + for (var i:uint = 0; i < goofs.length; ++i) { + var description:Description = Description.createTestDescription(fClass, "initializationError" + i); + var error:Object = goofs[i]; + runner.add(new ErrorReportingRunner(description, error)); + } + return runner; + } + + private function getCauses(cause:Object):Array + { + if (cause is InitializationError) { + return InitializationError(cause).causes; + } + return [cause]; + } + } +} Index: /as3/Syndication/trunk/tests/org/libspark/as3unit/inter/runners/ErrorReportingRunner.as =================================================================== --- /as3/Syndication/trunk/tests/org/libspark/as3unit/inter/runners/ErrorReportingRunner.as (リビジョン 952) +++ /as3/Syndication/trunk/tests/org/libspark/as3unit/inter/runners/ErrorReportingRunner.as (リビジョン 952) @@ -0,0 +1,46 @@ +/* + * Copyright(c) 2006 the Spark project. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, + * either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + */ + +package org.libspark.as3unit.inter.runners +{ + import org.libspark.as3unit.runner.Description; + import org.libspark.as3unit.runner.Runner; + import org.libspark.as3unit.runner.notification.RunNotifier; + + public class ErrorReportingRunner extends Runner + { + private var _description:Description; + private var cause:Object; + + public function ErrorReportingRunner(description:Description, cause:Object):void + { + _description = description; + this.cause = cause; + } + + public override function get description():Description + { + return _description; + } + + public override function run(notifier:RunNotifier):void + { + start(); + notifier.testAborted(_description, cause); + finish(); + } + } +} Index: /as3/Syndication/trunk/tests/org/libspark/as3unit/inter/runners/AsyncHelper.as =================================================================== --- /as3/Syndication/trunk/tests/org/libspark/as3unit/inter/runners/AsyncHelper.as (リビジョン 952) +++ /as3/Syndication/trunk/tests/org/libspark/as3unit/inter/runners/AsyncHelper.as (リビジョン 952) @@ -0,0 +1,153 @@ +/* + * Copyright(c) 2006 the Spark project. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, + * either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + */ + +package org.libspark.as3unit.inter.runners +{ + import flash.events.Event; + import flash.events.TimerEvent; + import flash.utils.Timer; + import org.libspark.as3unit.assert.AssertionFailedError; + + public class AsyncHelper + { + private static var fAsyncHelpers:Array = null; + + public static function setAsyncHelpersArray(arr:Array):void + { + fAsyncHelpers = arr; + } + + public static function addAsyncHelper(helper:AsyncHelper):void + { + if (fAsyncHelpers != null) { + helper.fParent = fAsyncHelpers; + fAsyncHelpers.push(helper); + } + } + + /* + public static function getAsyncHelpers():Array + { + return fAsyncHelpers.slice(); + } + + public static function clearAsyncHelpers():void + { + fAsyncHelpers.length = 0; + } + */ + + public function AsyncHelper(f:Function, timeout:uint) + { + fFunction = f; + fTimeout = timeout; + } + + private var fParent:Array; + private var fFunction:Function; + private var fTimeout:uint; + private var fTimer:Timer; + private var fCallback:Function; + private var fException:Object; + + public function get hasCalled():Boolean + { + return fFunction == null; + } + + public function get exception():Object + { + return fException; + } + + private function removeAsyncHelper():void + { + if (fParent != null) { + for (var i:uint = 0; i < fParent.length; ++i) { + if (fParent[i] == this) { + fParent.splice(i, 1); + break; + } + } + } + } + + public function start(callback:Function):void + { + if (fTimer == null) { + fCallback = callback; + fTimer = new Timer(fTimeout, 1); + fTimer.addEventListener(TimerEvent.TIMER, timeoutHandler); + fTimer.start(); + } + } + + public function stop():void + { + if (fTimer != null) { + fTimer.removeEventListener(TimerEvent.TIMER, timeoutHandler); + if (fTimer.running) { + fTimer.stop(); + } + fTimer = null; + } + } + + public function finalize():void + { + stop(); + fFunction = null; + } + + public function async(...args):void + { + stop(); + if (fFunction != null) { + // removeAsyncHelper(); + + var func:Function = fFunction; + fFunction = null; + + try { + setAsyncHelpersArray(fParent); + func.apply(null, args); + } + catch (e:Object) { + fException = e; + } + finally { + if (fCallback != null) { + fCallback(); + } + setAsyncHelpersArray(null); + } + } + } + + private function timeoutHandler(e:TimerEvent):void + { + stop(); + if (fFunction != null) { + removeAsyncHelper(); + fException = new TimeoutError('test timed out after ' + fTimeout + ' milliseconds'); + fFunction = null; + if (fCallback != null) { + fCallback(); + } + } + } + } +} Index: /as3/Syndication/trunk/tests/org/libspark/as3unit/inter/runners/Method.as =================================================================== --- /as3/Syndication/trunk/tests/org/libspark/as3unit/inter/runners/Method.as (リビジョン 952) +++ /as3/Syndication/trunk/tests/org/libspark/as3unit/inter/runners/Method.as (リビジョン 952) @@ -0,0 +1,118 @@ +/* + * Copyright(c) 2006 the Spark project. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, + * either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + */ + +package org.libspark.as3unit.inter.runners +{ + import flash.utils.describeType; + import flash.net.NetConnection; + import flash.errors.IllegalOperationError; + + public class Method + { + private var name_:String; + private var declaringClass_:Class; + private var returnType_:String; + private var parameters_:Array; + private var namespace_:Namespace; + private var isStatic_:Boolean; + + public static function getDeclaredMethods(klass:Class):Array + { + var results:Array = new Array(); + var classDescription:XML = describeType(klass); + for each (var methodXML:XML in classDescription.method) { + results.push(createMethod(klass, methodXML, true)); + } + for each (var factoryMethodXML:XML in classDescription.factory.method) { + results.push(createMethod(klass, factoryMethodXML, false)); + } + return results; + } + + private static function createMethod(klass:Class, methodXML:XML, isStatic:Boolean):Method + { + var method:Method = new Method(); + + method.declaringClass_ = klass; + method.name_ = String(methodXML.@name); + method.returnType_ = methodXML.@returnType; + method.isStatic_ = isStatic; + + if (methodXML.@uri != null) { + method.namespace_ = new Namespace(methodXML.@uri); + } + else { + method.namespace_ = null; + } + + method.parameters_ = new Array(); + for each (var parameterXML:XML in methodXML.parameter) { + method.parameters_.push(parameterXML.@type); + } + + return method; + } + + public function get declaringClass():Class + { + return declaringClass_; + } + + public function get namespace():Namespace + { + return namespace_; + } + + public function get name():String + { + return name_; + } + + public function get parameters():Array + { + return parameters_; + } + + public function get returnType():String + { + return returnType_; + } + + public function get isStatic():Boolean + { + return isStatic_; + } + + public function invoke(obj:Object, args:Array = null):* + { + if (isStatic) { + if (namespace != null) { + return declaringClass.namespace::[name].apply(obj, args); + } + else { + return declaringClass[name].apply(obj, args); + } + } + if (!(obj is declaringClass)) { + throw new IllegalOperationError('object is not declaringClass instance.'); + } + if (namespace != null) { + return obj.namespace::[name].apply(obj, args); + } + return obj[name].apply(obj, args); + } + } +} Index: /as3/Syndication/trunk/tests/org/libspark/as3unit/inter/runners/TestClassMethodsRunner.as =================================================================== --- /as3/Syndication/trunk/tests/org/libspark/as3unit/inter/runners/TestClassMethodsRunner.as (リビジョン 952) +++ /as3/Syndication/trunk/tests/org/libspark/as3unit/inter/runners/TestClassMethodsRunner.as (リビジョン 952) @@ -0,0 +1,159 @@ +/* + * Copyright(c) 2006 the Spark project. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, + * either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + */ + +package org.libspark.as3unit.inter.runners +{ + import org.libspark.as3unit.test; + import org.libspark.as3unit.runner.Description; + import org.libspark.as3unit.runner.Runner; + import org.libspark.as3unit.runner.manipulation.Filter; + import org.libspark.as3unit.runner.manipulation.Filterable; + import org.libspark.as3unit.runner.manipulation.NoTestsRemainException; + import org.libspark.as3unit.runner.manipulation.Sortable; + import org.libspark.as3unit.runner.manipulation.Sorter; + import org.libspark.as3unit.runner.notification.RunNotifier; + + import flash.utils.getQualifiedClassName; + + public class TestClassMethodsRunner extends Runner implements Filterable, Sortable + { + private var testMethods:Array; + private var fTestClass:Class; + + private var fIndex:uint; + private var fNotifier:RunNotifier; + + public function TestClassMethodsRunner(klass:Class) + { + fTestClass = klass; + testMethods = (new TestIntrospector(testClass).getTestMethods(test)); + } + + public override function run(notifier:RunNotifier):void + { + start(); + if (testMethods.length == 0) { + notifier.testAborted(description, new Error("No runnable methods")); + finish(); + return; + } + fIndex = 0; + fNotifier = notifier; + runTestMethod(); + } + + protected function runTestMethod():void + { + for (;;) { + var method:Method = testMethods[fIndex]; + var runner:Runner = createTestMethodRunner(method, fNotifier); + if (runner != null) { + runner.run(null); + } + if (++fIndex <= (testMethods.length - 1)) { + if (runner != null && !runner.hasFinised) { + runner.addCallback(runTestMethod); + break; + } + } + else { + if (runner != null && !runner.hasFinised) { + runner.addCallback(finish); + } + else { + finish(); + } + break; + } + } + } + + public override function get description():Description + { + var spec:Description = Description.createSuiteDescription(name); + for each (var method:Method in testMethods) { + spec.addChild(methodDescription(method)); + } + return spec; + } + + protected function get name():String + { + return getQualifiedClassName(testClass); + } + + protected function createTest():Object + { + return (new testClass()); + } + + protected function createTestMethodRunner(method:Method, notifier:RunNotifier):TestMethodRunner + { + var test:Object; + try { + test = createTest(); + } + catch (e:Error) { + notifier.testAborted(methodDescription(method), e); + return null; + } + return createMethodRunner(test, method, notifier); + } + + protected function createMethodRunner(test:Object, method:Method, notifier:RunNotifier):TestMethodRunner + { + return new TestMethodRunner(test, method, notifier, methodDescription(method)); + } + + protected function testName(method:Method):String + { + return method.name; + } + + protected function methodDescription(method:Method):Description + { + return Description.createTestDescription(testClass, testName(method)); + } + + public function filter(filter:Filter):void + { + for (var i:uint = 0; i < testMethods.length;) { + var method:Method = Method(testMethods[i]); + if (!filter.shouldRun(methodDescription(method))) { + testMethods.splice(i, 1); + } + else { + ++i; + } + } + if (testMethods.length == 0) { + throw new NoTestsRemainException(); + } + } + + public function sort(sorter:Sorter):void + { + testMethods.sort(function(o1:Method, o2:Method):int { + return sorter.compare(methodDescription(o1), methodDescription(o2)); + }); + } + + protected function get testClass():Class + { + return fTestClass; + } + } +} Index: /as3/Syndication/trunk/tests/org/libspark/as3unit/inter/runners/MethodValidator.as =================================================================== --- /as3/Syndication/trunk/tests/org/libspark/as3unit/inter/runners/MethodValidator.as (リビジョン 952) +++ /as3/Syndication/trunk/tests/org/libspark/as3unit/inter/runners/MethodValidator.as (リビジョン 952) @@ -0,0 +1,94 @@ +/* + * Copyright(c) 2006 the Spark project. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, + * either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + */ + +package org.libspark.as3unit.inter.runners +{ + import org.libspark.as3unit.after; + import org.libspark.as3unit.afterClass; + import org.libspark.as3unit.before; + import org.libspark.as3unit.beforeClass; + import org.libspark.as3unit.test; + + import flash.utils.describeType; + + public class MethodValidator + { + private var introspector:TestIntrospector; + private var errors:Array; + private var testClass:Class; + + public function MethodValidator(testClass:Class) + { + this.testClass = testClass; + introspector = new TestIntrospector(testClass); + errors = new Array(); + } + + public function validateInstanceMethods():void + { + validateTestMethods(after, false); + validateTestMethods(before, false); + validateTestMethods(test, false); + } + + public function validateStaticMethods():void + { + validateTestMethods(beforeClass, true); + validateTestMethods(afterClass, true); + } + + public function validateMethodsForDefaultRunner():Array + { + validateNoArgConstructor(); + validateStaticMethods(); + validateInstanceMethods(); + return errors; + } + + public function assertValid():void + { + if (errors.length > 0) { + throw new InitializationError(errors); + } + } + + public function validateNoArgConstructor():void + { + var constructor:XMLList = describeType(testClass).factory.constructor; + if (constructor != null) { + if (constructor.parameter.length() > 0) { + errors.push(new Error('Test class should have public zero-argument constructor')); + } + } + } + + private function validateTestMethods(annotation:Namespace, isStatic:Boolean):void + { + var methods:Array = introspector.getTestMethods(annotation); + for each (var each:Method in methods) { + if (each.isStatic != isStatic) { + errors.push(new Error('Method ' + each.name + '() ' + (isStatic ? 'should' : 'should not') + ' be static')); + } + if (each.returnType != 'void') { + errors.push(new Error('Method ' + each.name + '() should be void')); + } + if (each.parameters.length != 0) { + errors.push(new Error('Method ' + each.name + '() should have no parameters')); + } + } + } + } +} Index: /as3/Syndication/trunk/tests/org/libspark/as3unit/inter/runners/AsyncError.as =================================================================== --- /as3/Syndication/trunk/tests/org/libspark/as3unit/inter/runners/AsyncError.as (リビジョン 952) +++ /as3/Syndication/trunk/tests/org/libspark/as3unit/inter/runners/AsyncError.as (リビジョン 952) @@ -0,0 +1,26 @@ +/* + * Copyright(c) 2006 the Spark project. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, + * either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + */ + +package org.libspark.as3unit.inter.runners +{ + public class AsyncError extends Error + { + public function AsyncError(message:String = '', id:int = 0) + { + super(message, id); + } + } +} Index: /as3/Syndication/trunk/tests/org/libspark/as3unit/inter/runners/TextListener.as =================================================================== --- /as3/Syndication/trunk/tests/org/libspark/as3unit/inter/runners/TextListener.as (リビジョン 952) +++ /as3/Syndication/trunk/tests/org/libspark/as3unit/inter/runners/TextListener.as (リビジョン 952) @@ -0,0 +1,128 @@ +/* + * Copyright(c) 2006 the Spark project. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, + * either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + */ + +package org.libspark.as3unit.inter.runners +{ + import org.libspark.as3unit.runner.Description; + import org.libspark.as3unit.runner.Result; + import org.libspark.as3unit.runner.notification.Failure; + import org.libspark.as3unit.runner.notification.RunListener; + + public class TextListener extends RunListener + { + private var buffer:String; + + public function TextListener() + { + buffer = ''; + } + + public override function testRunFinished(result:Result):void + { + printHeader(result.runTime); + printFailures(result); + printFooter(result); + } + + public override function testStarted(description:Description):void + { + print('.'); + } + + public override function testFailure(failure:Failure):void + { + print('E'); + } + + public override function testIgnored(description:Description):void + { + print('I'); + } + + protected function printHeader(runTime:uint):void + { + println(); + println('Time: ' + elapsedTimeAsString(runTime)); + } + + protected function printFailures(result:Result):void + { + if (result.failureCount == 0) { + return; + } + if (result.failureCount == 1) { + println('There was ' + result.failureCount + ' failure:'); + } + else { + println('There were ' + result.failureCount + ' failures:'); + } + var i:uint = 0; + for each (var failure:Failure in result.failures) { + printFailure(failure, ++i); + } + } + + protected function printFailure(failure:Failure, count:uint):void + { + printFailureHeader(failure, count); + printFailureTrace(failure); + } + + protected function printFailureHeader(failure:Failure, count:uint):void + { + println(count + ') ' + failure.testHeader); + } + + protected function printFailureTrace(failure:Failure):void + { + println(failure.trace); + } + + protected function printFooter(result:Result):void + { + if (result.wasSuccessful) { + println(); + print('OK'); + println(' (' + result.runCount + ' test' + (result.runCount == 1 ? '' : 's') + ')'); + } + else { + println(); + println('FAILURES!!!!'); + println('Tests run: ' + result.runCount + ', Failure: ' + result.failureCount); + } + println(); + } + + protected function elapsedTimeAsString(runTime:uint):String + { + return String(runTime / 1000); + } + + private function print(str:String):void + { + buffer += str; + if (buffer.length >= 80) { + println(); + } + } + + private function println(str:String=''):void + { + trace(buffer + str); + buffer = ''; + } + } +} Index: /as3/Syndication/trunk/tests/org/libspark/as3unit/inter/runners/TestIntrospector.as =================================================================== --- /as3/Syndication/trunk/tests/org/libspark/as3unit/inter/runners/TestIntrospector.as (リビジョン 952) +++ /as3/Syndication/trunk/tests/org/libspark/as3unit/inter/runners/TestIntrospector.as (リビジョン 952) @@ -0,0 +1,83 @@ +/* + * Copyright(c) 2006 the Spark project. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, + * either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + */ + +package org.libspark.as3unit.inter.runners +{ + import org.libspark.as3unit.before; + import org.libspark.as3unit.beforeClass; + import org.libspark.as3unit.ignore; + import org.libspark.as3unit.test; + import org.libspark.as3unit.test_expected; + + public class TestIntrospector + { + private var testClass:Class; + + public function TestIntrospector(testClass:Class) + { + this.testClass = testClass; + } + + public function getTestMethods(annotationNamespace:Namespace):Array + { + var results:Array = new Array(); + var annotationURI:String = annotationNamespace.uri; + + for each (var method:Method in Method.getDeclaredMethods(testClass)) { + if (method.namespace.uri == annotationURI) { + results.push(method); + } + } + + if (runTopToBottom(annotationNamespace)) { + results.reverse(); + } + + return results; + } + + public function isIgnored(eachMethod:Method):Boolean + { + try { + eachMethod.declaringClass.ignore::[eachMethod.name]; + return true; + } + catch (e:ReferenceError) { + } + return false; + } + + private function runTopToBottom(annotation:Namespace):Boolean + { + return (annotation.uri == before.uri) || (annotation.uri == beforeClass.uri); + } + + internal function getTimeout(method:Method):uint + { + return 0; + } + + internal function expectedException(method:Method):Class + { + try { + return method.declaringClass.test_expected::[method.name]; + } + catch (e:ReferenceError) { + } + return null; + } + } +} Index: /as3/Syndication/trunk/tests/org/libspark/as3unit/inter/runners/CompositeRunner.as =================================================================== --- /as3/Syndication/trunk/tests/org/libspark/as3unit/inter/runners/CompositeRunner.as (リビジョン 952) +++ /as3/Syndication/trunk/tests/org/libspark/as3unit/inter/runners/CompositeRunner.as (リビジョン 952) @@ -0,0 +1,129 @@ +/* + * Copyright(c) 2006 the Spark project. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, + * either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + */ + +package org.libspark.as3unit.inter.runners +{ + import org.libspark.as3unit.runner.Description; + import org.libspark.as3unit.runner.Runner; + import org.libspark.as3unit.runner.manipulation.Filter; + import org.libspark.as3unit.runner.manipulation.Filterable; + import org.libspark.as3unit.runner.manipulation.NoTestsRemainException; + import org.libspark.as3unit.runner.manipulation.Sortable; + import org.libspark.as3unit.runner.manipulation.Sorter; + import org.libspark.as3unit.runner.notification.RunNotifier; + + public class CompositeRunner extends Runner implements Filterable, Sortable + { + private var fRunners:Array; + private var fName:String; + + private var fIndex:uint; + private var fNotifier:RunNotifier; + + public function CompositeRunner(name:String) + { + fRunners = new Array(); + fName = name; + } + + public override function run(notifier:RunNotifier):void + { + start(); + if (fRunners.length == 0) { + finish(); + return; + } + fIndex = 0; + fNotifier = notifier; + runChildRunner(); + } + + protected function runChildRunner():void + { + for (;;) { + var runner:Runner = fRunners[fIndex]; + runner.run(fNotifier); + if (++fIndex <= (fRunners.length - 1)) { + if (!runner.hasFinised) { + runner.addCallback(runChildRunner); + break; + } + } + else { + if (!runner.hasFinised) { + runner.addCallback(finish); + } + else { + finish(); + } + break; + } + } + } + + public override function get description():Description + { + var spec:Description = Description.createSuiteDescription(fName); + for each (var runner:Runner in fRunners) { + spec.addChild(runner.description); + } + return spec; + } + + public function get runners():Array + { + return fRunners; + } + + public function addAll(runners:Array):void + { + fRunners = fRunners.concat(runners); + } + + public function add(runner:Runner):void + { + fRunners.push(runner); + } + + public function filter(filter:Filter):void + { + for (var i:uint = 0; i < fRunners.length; ++i) { + var runner:Runner = Runner(fRunners[i]); + if (filter.shouldRun(runner.description)) { + filter.apply(runner); + } + else { + fRunners.splice(i, 1); + } + } + } + + protected function get name():String + { + return fName; + } + + public function sort(sorter:Sorter):void + { + fRunners.sort(function(o1:Runner, o2:Runner):int { + return sorter.compare(o1.description, o2.description); + }); + for each (var runner:Runner in fRunners) { + sorter.apply(runner); + } + } + } +} Index: /as3/Syndication/trunk/tests/org/libspark/as3unit/inter/runners/OldTestClassRunner.as =================================================================== --- /as3/Syndication/trunk/tests/org/libspark/as3unit/inter/runners/OldTestClassRunner.as (リビジョン 952) +++ /as3/Syndication/trunk/tests/org/libspark/as3unit/inter/runners/OldTestClassRunner.as (リビジョン 952) @@ -0,0 +1,166 @@ +/* + * Copyright(c) 2006 the Spark project. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, + * either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + */ + +package org.libspark.as3unit.inter.runners +{ + import org.libspark.asunit.extensions.TestDecorator; + import org.libspark.asunit.framework.AssertionFailedError; + import org.libspark.asunit.framework.AS3UnitTestAdapter; + import org.libspark.asunit.framework.AS3UnitTestCaseFacade; + import org.libspark.asunit.framework.Test; + import org.libspark.asunit.framework.TestCase; + import org.libspark.asunit.framework.TestListener; + import org.libspark.asunit.framework.TestResult; + import org.libspark.asunit.framework.TestSuite; + import org.libspark.as3unit.runner.Description; + import org.libspark.as3unit.runner.Runner; + import org.libspark.as3unit.runner.notification.RunNotifier; + import org.libspark.as3unit.runner.notification.Failure; + import org.libspark.as3unit.inter.runners.OldTestClassRunner; + import org.libspark.as3unit.inter.runners.OldTestClassRunner; + import org.libspark.asunit.framework.TestSuite; + import org.libspark.as3unit.runner.notification.Failure; + + import flash.utils.getQualifiedClassName; + + public class OldTestClassRunner extends Runner + { + private var test:Test; + + public function OldTestClassRunner(test:*) + { + if (test is Class) { + this.test = new TestSuite(test); + } + else if (test is Test) { + this.test = test; + } + else { + throw new TypeError(); + } + } + + public override function run(notifier:RunNotifier):void + { + start(); + var result:TestResult = new TestResult(); + result.addListener(createAdaptingListener(notifier)); + test.run(result); + finish(); + } + + public static function createAdaptingListener(notifier:RunNotifier):TestListener + { + return new OldTestClassAdaptingListener(notifier); + } + + public override function get description():Description + { + return makeDescription(test); + } + + private function makeDescription(test:Test):Description + { + if (test is TestCase) { + var tc:TestCase = TestCase(test); + return Description.createTestDescription(getClass(tc), tc.getName()); + } + else if (test is TestSuite) { + var ts:TestSuite = TestSuite(test); + var description:Description = Description.createSuiteDescription(ts.name); + var n:uint = ts.testCount; + for (var i:uint = 0; i < n; ++i) { + description.addChild(makeDescription(ts.testAt(i))); + } + return description; + } + else if (test is AS3UnitTestAdapter) { + return AS3UnitTestAdapter(test).description; + } + else if (test is TestDecorator) { + return makeDescription(TestDecorator(test).test); + } + else { + return Description.createSuiteDescription(getQualifiedClassName(getClass(test))); + } + } + + private function getClass(instance:Object):Class + { + return instance.constructor; + } + } +} + +import org.libspark.as3unit.runner.notification.RunNotifier; +import org.libspark.as3unit.runner.notification.Failure; +import org.libspark.as3unit.runner.Description; +import org.libspark.asunit.framework.TestListener; +import org.libspark.asunit.framework.Test; +import org.libspark.asunit.framework.TestCase; +import org.libspark.asunit.framework.TestSuite; +import org.libspark.asunit.framework.AS3UnitTestCaseFacade; +import org.libspark.asunit.framework.AssertionFailedError; + +import flash.utils.getQualifiedClassName; + +class OldTestClassAdaptingListener implements TestListener +{ + private var notifier:RunNotifier; + + public function OldTestClassAdaptingListener(notifier:RunNotifier) + { + this.notifier = notifier; + } + + public function endTest(test:Test):void + { + notifier.fireTestFinished(asDescription(test)); + } + + public function startTest(test:Test):void + { + notifier.fireTestStarted(asDescription(test)); + } + + public function addError(test:Test, e:Object):void + { + var failure:Failure = new Failure(asDescription(test), e); + notifier.fireTestFailure(failure); + } + + private function asDescription(test:Test):Description + { + if (test is AS3UnitTestCaseFacade) { + return AS3UnitTestCaseFacade(test).description; + } + return Description.createTestDescription(Object(test).constructor, getName(test)); + } + + private function getName(test:Test):String + { + if (test is TestCase) { + return TestCase(test).getName(); + } + else { + return String(test); + } + } + + public function addFailure(test:Test, t:AssertionFailedError):void { + addError(test, t); + } +} Index: /as3/Syndication/trunk/tests/org/libspark/as3unit/inter/runners/TestClassRunner.as =================================================================== --- /as3/Syndication/trunk/tests/org/libspark/as3unit/inter/runners/TestClassRunner.as (リビジョン 952) +++ /as3/Syndication/trunk/tests/org/libspark/as3unit/inter/runners/TestClassRunner.as (リビジョン 952) @@ -0,0 +1,139 @@ +/* + * Copyright(c) 2006 the Spark project. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, + * either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + */ + +package org.libspark.as3unit.inter.runners +{ + import org.libspark.as3unit.afterClass; + import org.libspark.as3unit.beforeClass; + import org.libspark.as3unit.runner.Description; + import org.libspark.as3unit.runner.Runner; + import org.libspark.as3unit.runner.manipulation.Filter; + import org.libspark.as3unit.runner.manipulation.Filterable; + import org.libspark.as3unit.runner.manipulation.NoTestsRemainException; + import org.libspark.as3unit.runner.manipulation.Sortable; + import org.libspark.as3unit.runner.manipulation.Sorter; + import org.libspark.as3unit.runner.notification.RunNotifier; + import org.libspark.as3unit.runner.notification.Failure; + import org.libspark.as3unit.runner.notification.RunNotifier; + + public class TestClassRunner extends Runner implements Filterable, Sortable + { + protected var enclosedRunner:Runner; + private var fTestClass:Class; + + public function TestClassRunner(klass:Class, runner:Runner=null) + { + fTestClass = klass; + if (runner == null) { + runner = new TestClassMethodsRunner(klass); + } + enclosedRunner = runner; + var methodValidator:MethodValidator = new MethodValidator(klass); + validate(methodValidator); + methodValidator.assertValid(); + } + + protected function validate(methodValidator:MethodValidator):void + { + methodValidator.validateMethodsForDefaultRunner(); + } + + public override function run(notifier:RunNotifier):void + { + start(); + var runner:BeforeAndAfterRunner = new BeforeClassAndAfterClassRunner( + testClass, enclosedRunner, notifier, description); + runner.run(null); + if (!runner.hasFinised) { + runner.addCallback(finish); + } + else { + finish(); + } + } + + public override function get description():Description + { + return enclosedRunner.description; + } + + public function filter(filter:Filter):void + { + filter.apply(enclosedRunner); + } + + public function sort(sorter:Sorter):void + { + sorter.apply(enclosedRunner); + } + + protected function get testClass():Class + { + return fTestClass; + } + } +} + +import org.libspark.as3unit.beforeClass; +import org.libspark.as3unit.afterClass; +import org.libspark.as3unit.inter.runners.BeforeAndAfterRunner; +import org.libspark.as3unit.runner.Runner; +import org.libspark.as3unit.runner.Description; +import org.libspark.as3unit.runner.notification.RunNotifier; +import org.libspark.as3unit.runner.notification.Failure; + +class BeforeClassAndAfterClassRunner extends BeforeAndAfterRunner +{ + private var runner:Runner; + private var notifier:RunNotifier; + private var fDescription:Description; + + public function BeforeClassAndAfterClassRunner(klass:Class, + runner:Runner, notifier:RunNotifier, description:Description) + { + super(klass, beforeClass, afterClass, null); + this.runner = runner; + this.notifier = notifier; + this.fDescription = description; + } + + public override function run(n:RunNotifier):void + { + start(); + runProtected(); + } + + protected override function runUnprotected():void + { + runner.run(notifier); + if (!runner.hasFinised) { + runner.addCallback(runUnprotectedComplete); + } + else { + runUnprotectedComplete(); + } + } + + protected override function runFinished():void + { + finish(); + } + + protected override function addFailure(targetException:Object):void + { + notifier.fireTestFailure(new Failure(fDescription, targetException)); + } +} Index: /as3/Syndication/trunk/tests/org/libspark/as3unit/inter/runners/TimeoutError.as =================================================================== --- /as3/Syndication/trunk/tests/org/libspark/as3unit/inter/runners/TimeoutError.as (リビジョン 952) +++ /as3/Syndication/trunk/tests/org/libspark/as3unit/inter/runners/TimeoutError.as (リビジョン 952) @@ -0,0 +1,26 @@ +/* + * Copyright(c) 2006 the Spark project. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, + * either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + */ + +package org.libspark.as3unit.inter.runners +{ + public class TimeoutError extends Error + { + public function TimeoutError(message:String = '', id:int = 0) + { + super(message, id); + } + } +} Index: /as3/Syndication/trunk/tests/org/libspark/as3unit/inter/runners/InitializationError.as =================================================================== --- /as3/Syndication/trunk/tests/org/libspark/as3unit/inter/runners/InitializationError.as (リビジョン 952) +++ /as3/Syndication/trunk/tests/org/libspark/as3unit/inter/runners/InitializationError.as (リビジョン 952) @@ -0,0 +1,43 @@ +/* + * Copyright(c) 2006 the Spark project. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, + * either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + */ + +package org.libspark.as3unit.inter.runners +{ + public class InitializationError extends Error + { + private var errors:Array; + + public static function createWithString(string:String):InitializationError + { + return createWithErrors(new Error(string)); + } + + public static function createWithErrors(...errors):InitializationError + { + return new InitializationError(errors); + } + + public function InitializationError(errors:Array) + { + this.errors = errors; + } + + public function get causes():Array + { + return errors; + } + } +} Index: /as3/Syndication/trunk/tests/org/libspark/as3unit/inter/runners/BeforeAndAfterRunner.as =================================================================== --- /as3/Syndication/trunk/tests/org/libspark/as3unit/inter/runners/BeforeAndAfterRunner.as (リビジョン 952) +++ /as3/Syndication/trunk/tests/org/libspark/as3unit/inter/runners/BeforeAndAfterRunner.as (リビジョン 952) @@ -0,0 +1,120 @@ +/* + * Copyright(c) 2006 the Spark project. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, + * either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + */ + +package org.libspark.as3unit.inter.runners +{ + import org.libspark.as3unit.runner.Runner; + + public class BeforeAndAfterRunner extends Runner + { + private var beforeAnnotation:Namespace; + private var afterAnnotation:Namespace; + private var testIntrospector:TestIntrospector; + private var test:Object; + private var unprotectedComplete:Boolean; + + public function BeforeAndAfterRunner(testClass:Class, + beforeAnnotation:Namespace, + afterAnnotation:Namespace, + test:Object) + { + this.beforeAnnotation = beforeAnnotation; + this.afterAnnotation = afterAnnotation; + testIntrospector = new TestIntrospector(testClass); + this.test = test; + } + + public function runProtected():void + { + try { + runBefores(); + } + catch (e:FailedBefore) { + runUnprotectedComplete(); + return; + } + var noException:Boolean = false; + try { + unprotectedComplete = false; + runUnprotected(); + noException = true; + } + finally { + if (!noException && !runUnprotectedComplete) { + runUnprotectedComplete(); + } + } + } + + protected function runUnprotected():void + { + throw new DefinitionError('Subclass must override this method.'); + } + + protected function runUnprotectedComplete():void + { + unprotectedComplete = true; + runAfters(); + runFinished(); + } + + protected function addFailure(targetException:Object):void + { + throw new DefinitionError('Subclass must override this method.'); + } + + private function runBefores():void + { + try { + var befores:Array = testIntrospector.getTestMethods(beforeAnnotation); + for each (var before:Method in befores) { + invokeMethod(before); + } + } + catch (e:Object) { + addFailure(e); + throw new FailedBefore(); + } + } + + private function runAfters():void + { + var afters:Array = testIntrospector.getTestMethods(afterAnnotation); + for each (var after:Method in afters) { + try { + invokeMethod(after); + } + catch (e:Object) { + addFailure(e); + } + } + } + + protected function runFinished():void + { + + } + + private function invokeMethod(method:Method):void + { + method.invoke(test); + } + } +} + +class FailedBefore extends Error +{ +} Index: /as3/Syndication/trunk/tests/org/libspark/as3unit/inter/runners/XMLListener.as =================================================================== --- /as3/Syndication/trunk/tests/org/libspark/as3unit/inter/runners/XMLListener.as (リビジョン 952) +++ /as3/Syndication/trunk/tests/org/libspark/as3unit/inter/runners/XMLListener.as (リビジョン 952) @@ -0,0 +1,98 @@ +/* + * Copyright(c) 2006-2007 the Spark project. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, + * either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + */ + +package org.libspark.as3unit.inter.runners +{ + import org.libspark.as3unit.runner.notification.RunListener; + import org.libspark.as3unit.runner.Description; + import org.libspark.as3unit.runner.Result; + import org.libspark.as3unit.runner.notification.Failure; + import flash.utils.Dictionary; + + public class XMLListener extends RunListener + { + private var descriptionMap:Dictionary; + private var resultXML:XML = ; + + public function get result():XML + { + return resultXML; + } + + public override function testRunStarted(description:Description):void + { + descriptionMap = new Dictionary(); + resultXML = + + if (description.isSuite) { + for each (var child:Description in description.children) { + buildResultXML(child, resultXML); + } + } + else { + buildResultXML(description, resultXML); + } + } + + private function buildResultXML(description:Description, xml:XML):void + { + if (description.isSuite) { + var suiteXML:XML = ; + for each (var child:Description in description.children) { + buildResultXML(child, suiteXML); + } + xml.appendChild(suiteXML); + } + else { + var displayName:String = description.displayName; + var endIndex:uint = displayName.indexOf("("); + var testName:String = displayName.substring(0, endIndex >= 0 ? endIndex : displayName.length); + var testXML:XML = + descriptionMap[description.displayName] = testXML; + xml.appendChild(testXML); + } + } + + public override function testRunFinished(result:Result):void + { + descriptionMap = null; + } + + public override function testStarted(description:Description):void + { + } + + public override function testFinished(description:Description):void + { + var testXML:XML = descriptionMap[description.displayName]; + if (testXML.@status == "n") { + testXML.@status = "o"; + } + } + + public override function testFailure(failure:Failure):void + { + var testXML:XML = descriptionMap[failure.description.displayName]; + testXML.@status = "f"; + testXML.@trace = failure.trace; + } + + public override function testIgnored(description:Description):void + { + descriptionMap[description.displayName].@status = "i"; + } + } +} Index: /as3/Syndication/trunk/tests/org/libspark/as3unit/inter/runners/TestMethodRunner.as =================================================================== --- /as3/Syndication/trunk/tests/org/libspark/as3unit/inter/runners/TestMethodRunner.as (リビジョン 952) +++ /as3/Syndication/trunk/tests/org/libspark/as3unit/inter/runners/TestMethodRunner.as (リビジョン 952) @@ -0,0 +1,194 @@ +/* + * Copyright(c) 2006 the Spark project. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, + * either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + */ + +package org.libspark.as3unit.inter.runners +{ + import org.libspark.as3unit.after; + import org.libspark.as3unit.before; + import org.libspark.as3unit.assert.AssertionFailedError; + import org.libspark.as3unit.runner.Description; + import org.libspark.as3unit.runner.notification.RunNotifier; + import org.libspark.as3unit.runner.notification.Failure; + + import flash.utils.getQualifiedClassName; + + public class TestMethodRunner extends BeforeAndAfterRunner + { + private var test:Object; + private var method:Method; + private var notifier:RunNotifier; + private var testIntrospector:TestIntrospector; + private var fDescription:Description; + private var fAsyncHelpers:Array = []; + private var fAsync:AsyncHelper; + + public function TestMethodRunner(test:Object, method:Method, notifier:RunNotifier, description:Description) + { + super(test.constructor, before, after, test); + this.test = test; + this.method = method; + this.notifier = notifier; + testIntrospector = new TestIntrospector(test.constructor); + this.fDescription = description; + } + + public override function run(n:RunNotifier):void + { + start(); + if (testIntrospector.isIgnored(method)) { + notifier.fireTestIgnored(fDescription); + finish(); + return; + } + notifier.fireTestStarted(fDescription); + runMethod(); + } + + private function runMethod():void + { + runProtected(); + } + + protected override function runUnprotected():void + { + fAsyncHelpers.length = 0; + AsyncHelper.setAsyncHelpersArray(fAsyncHelpers); + fAsync = null; + runUnprotectedAsync(); + } + + protected function runUnprotectedAsync():void + { + var failed:Boolean = false; + var exception:Object = null; + var needsCheckExceptoin:Boolean = true; + var asyncHelpers:Array = []; + + try { + if (fAsync != null) { + if (fAsync.exception != null) { + exception = fAsync.exception; + } + fAsync = null; + } + else { + executeMethodBody(); + } + + AsyncHelper.setAsyncHelpersArray(null); + + for (var i:uint = 0; i < fAsyncHelpers.length; ) { + var helper:AsyncHelper = AsyncHelper(fAsyncHelpers[i]); + if (helper.hasCalled) { + if (exception == null && helper.exception != null) { + exception = helper.exception; + } + fAsyncHelpers.splice(i, 1); + } + else { + ++i; + } + } + + if (fAsyncHelpers.length > 1) { + for each (var async:AsyncHelper in fAsyncHelpers) { + async.finalize(); + } + fAsyncHelpers.length = 0; + exception = new AsyncError('Too many async points.'); + } + else if (fAsyncHelpers.length == 1) { + fAsync = AsyncHelper(fAsyncHelpers[0]); + fAsyncHelpers.length = 0; + if (exception == null) { + fAsync.start(runUnprotectedAsync); + } + } + } + catch (e:Object) { + exception = e; + } + finally { + if (fAsync == null || exception != null) { + if (exception != null) { + if (fAsync != null) { + fAsync.finalize(); + fAsync = null; + } + checkExpectedException(exception); + } + else { + checkExceptsException(); + } + runUnprotectedComplete(); + } + } + } + + protected function checkExceptsException():Boolean + { + if (exceptsException) { + addFailure(new AssertionFailedError('Expected exception: ' + getQualifiedClassName(expectedException))); + return true; + } + return false; + } + + protected function checkExpectedException(e:Object):Boolean + { + if (!exceptsException) { + addFailure(e); + return true; + } + else if (isUnexpected(e)) { + addFailure(new Error('Unexpected exception, expected<' + getQualifiedClassName(expectedException) + '> but was<' + getQualifiedClassName(e) + '>')); + return true; + } + return false; + } + + protected override function runFinished():void + { + notifier.fireTestFinished(fDescription); + finish(); + } + + protected function executeMethodBody():void + { + method.invoke(test); + } + + protected override function addFailure(e:Object):void + { + notifier.fireTestFailure(new Failure(fDescription, e)); + } + + private function get exceptsException():Boolean + { + return expectedException != null; + } + + private function get expectedException():Class + { + return testIntrospector.expectedException(method); + } + + private function isUnexpected(exception:Object):Boolean + { + return !(exception is expectedException); + } + } +} Index: /as3/Syndication/trunk/tests/org/libspark/as3unit/test.as =================================================================== --- /as3/Syndication/trunk/tests/org/libspark/as3unit/test.as (リビジョン 952) +++ /as3/Syndication/trunk/tests/org/libspark/as3unit/test.as (リビジョン 952) @@ -0,0 +1,38 @@ +/* + * Copyright(c) 2006 the Spark project. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, + * either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + */ + +package org.libspark.as3unit +{ + /** + * The test namespace tells AS3Unit that the void method + * to which it is attached can be run as a test case. To run the method, + * AS3Unit first constructs a fresh instance of the class then invokes the + * test method. Any exception thrown by the test will be reported + * by AS3Unit as a failure. If no exceptions are thrown, the test is assumed + * to have succeeded. + * + * A simple test looks like this: + * + * + * public class Example { + * test function method():void { + * trace('Hello'); + * } + * } + * + */ + public namespace test = 'http://as3unit.libspark.org/test'; +} Index: /as3/Syndication/trunk/tests/org/libspark/as3unit/test_expected.as =================================================================== --- /as3/Syndication/trunk/tests/org/libspark/as3unit/test_expected.as (リビジョン 952) +++ /as3/Syndication/trunk/tests/org/libspark/as3unit/test_expected.as (リビジョン 952) @@ -0,0 +1,32 @@ +/* + * Copyright(c) 2006 the Spark project. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, + * either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + */ + +package org.libspark.as3unit +{ + /** + * The test_expected declares that a test method should throw + * an exception. If it doesn't throw an exception or if it throws a different + * exception than the one declared, the test fails. For example, the following + * test succeeds: + * + * test_excepted static const outOfBounds:Class = RangeError; + * test function outOfBounds():void { + * var value:* = (new Array(0))[1]; + * } + * + */ + public namespace test_expected = 'http://as3unit.libspark.org/test_expected'; +} Index: /as3/Syndication/trunk/tests/org/libspark/as3unit/after.as =================================================================== --- /as3/Syndication/trunk/tests/org/libspark/as3unit/after.as (リビジョン 952) +++ /as3/Syndication/trunk/tests/org/libspark/as3unit/after.as (リビジョン 952) @@ -0,0 +1,45 @@ +/* + * Copyright(c) 2006 the Spark project. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, + * either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + */ + +package org.libspark.as3unit +{ + /** + * If you allocate external resources in a before method you need to release them + * after the test runs. Declaring a void method with after namespace + * that method to be run after the test method. All after methods are + * guaranteed to run even if a before or test method throws an exception. + * + * For example: + * + * + * public class Example { + * private var bitmap:BitmapData; + * before function createBitmapData():void { + * bitmap = new BitmapData(200, 200); + * } + * test function something():void { + * ... + * } + * after function disposeBitmapData():void { + * bitmap.dispose(); + * } + * } + * + * + * @see org.libspark.as3unit.before + */ + public namespace after = 'http://as3unit.libspark.org/after'; +} Index: /as3/Syndication/trunk/tests/org/libspark/as3unit/before.as =================================================================== --- /as3/Syndication/trunk/tests/org/libspark/as3unit/before.as (リビジョン 952) +++ /as3/Syndication/trunk/tests/org/libspark/as3unit/before.as (リビジョン 952) @@ -0,0 +1,42 @@ +/* + * Copyright(c) 2006 the Spark project. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, + * either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + */ + +package org.libspark.as3unit +{ + /** + * When writing tests, it is common to find that serveral tests need similar + * objects created before they can run. Declaring a void method + * with before namespace that method to be run before the test method. + * + * For exapmle: + * + * + * public class Example { + * private var empty:Array; + * before static function initialize():void { + * empty = new Array(); + * } + * test function size():void { + * ... + * } + * } + * + * + * @see org.libspark.as3unit.beforeClass + * @see org.libspark.as3unit.after + */ + public namespace before = 'http://as3unit.libspark.org/before'; +} Index: /as3/Syndication/trunk/tests/org/libspark/as3unit/components/AS3Unit.mxml =================================================================== --- /as3/Syndication/trunk/tests/org/libspark/as3unit/components/AS3Unit.mxml (リビジョン 952) +++ /as3/Syndication/trunk/tests/org/libspark/as3unit/components/AS3Unit.mxml (リビジョン 952) @@ -0,0 +1,132 @@ + + + + + 0 ? 0xFF0000 : 0x00FF00); + testResult = resultXML; + callLater(initializeTestTree); + } + + private function createProgressLabel(result:Result):String + { + return "Run: " + result.runCount + " Failure: " + result.failureCount + " Ignore: " + result.ignoreCount + " Time: " + formatTime(result.runTime); + } + + private function formatTime(time:uint):String + { + return (time / 1000).toString(); + } + + private function initializeTestTree():void + { + for each (var suiteXML:XML in testResult..suite) { + if (suiteXML..test.(@status == "f").length() > 0) { + testTree.setItemIcon(suiteXML, f, f); + } + else { + testTree.setItemIcon(suiteXML, o, o); + } + } + testTree.expandChildrenOf(testResult, true); + } + + private function testTreeItemClickHandler():void + { + updateItemDetail(testTree.selectedItem as XML); + } + + private function failuresListItemClickHandler():void + { + updateItemDetail(failuresList.selectedItem as XML); + } + + private function updateItemDetail(item:XML):void + { + if (item && item.localName() == "test") { + if (item.@status == "f") { + detailField.text = item.@trace; + testTree.selectedItem = item; + testTree.firstVisibleItem = item; + failuresList.selectedItem = item; + } + else { + detailField.text = ""; + } + } + } + ]]> + + + + + + + + + + + + + + + + + + Index: /as3/Syndication/trunk/tests/org/libspark/as3unit/ignore.as =================================================================== --- /as3/Syndication/trunk/tests/org/libspark/as3unit/ignore.as (リビジョン 952) +++ /as3/Syndication/trunk/tests/org/libspark/as3unit/ignore.as (リビジョン 952) @@ -0,0 +1,41 @@ +/* + * Copyright(c) 2006 the Spark project. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, + * either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + */ + +package org.libspark.as3unit +{ + /** + * Sometimes you want to temporarlly disable a test. Methods annotated with test + * that are also annotated with ignore will not be executed as tests. Native + * AS3Unit test runners should report the number of ignored tests along with the number of + * tests that ran and the number of tests that failed. + * For example: + * + * ignore static const something:String; + * test function something():void { + * ... + * } + * + * Please create static const property with same name as test method. + * If you want to record why a test is being ignored, set string constant. + * + * ignore static const something:String = 'not ready yet'; + * test function something():void { + * ... + * } + * + */ + public namespace ignore = 'http://as3unit.libspark.org/ignore'; +} Index: /as3/Syndication/trunk/tests/org/libspark/as3unit/afterClass.as =================================================================== --- /as3/Syndication/trunk/tests/org/libspark/as3unit/afterClass.as (リビジョン 952) +++ /as3/Syndication/trunk/tests/org/libspark/as3unit/afterClass.as (リビジョン 952) @@ -0,0 +1,45 @@ +/* + * Copyright(c) 2006 the Spark project. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, + * either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + */ + +package org.libspark.as3unit +{ + /** + * If you allocate expensive external resources in a beforeClass method you need to release them + * after all the tests in the class have run. Declaring a static void method + * with afterClass namespace that method to be run after all the tests in the class have been run. + * All afterClass methods are guaranteed to run even if a beforeClass method thrown an + * exception. + * + * For example: + * + * + * public class Example { + * var bitmap:BitmapData; + * beforeClass static function allocate():void { + * bitmap = new BitmapData(200, 200); + * } + * test function something():void { + * } + * afterClass static function dispose():void { + * bitmap.dispose(); + * } + * } + * + * + * @see org.libspark.as3unit.beforeClass + */ + public namespace afterClass = 'http://as3unit.libspark.org/afterClass'; +} Index: /as3/Syndication/trunk/tests/org/libspark/as3unit/runner/Result.as =================================================================== --- /as3/Syndication/trunk/tests/org/libspark/as3unit/runner/Result.as (リビジョン 952) +++ /as3/Syndication/trunk/tests/org/libspark/as3unit/runner/Result.as (リビジョン 952) @@ -0,0 +1,147 @@ +/* + * Copyright(c) 2006 the Spark project. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, + * either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + */ + +package org.libspark.as3unit.runner +{ + import org.libspark.as3unit.runner.notification.Failure; + import org.libspark.as3unit.runner.notification.RunListener; + + /** + * A Result collects and summarizes inromation from running multiple + * tests. Since tests are expected to run correctly, successful tests are only noted in + * the count of tests that ran. + */ + public class Result + { + private var value:ResultValue; + + public function Result() + { + value = new ResultValue(); + value.count = 0; + value.ignoreCount = 0; + value.failures = new Array(); + value.runTime = 0; + } + + /** + * @return the number or tests run + */ + public function get runCount():uint + { + return value.count; + } + + /** + * @return the number of tests that failed during the run + */ + public function get failureCount():uint + { + return value.failures.length; + } + + /** + * @return the number of milliseconds it took to run the entire suite to run + */ + public function get runTime():uint + { + return value.runTime; + } + + /** + * @return the Failures describing tests that failed and the problems they encountered + */ + public function get failures():Array + { + return value.failures; + } + + /** + * @return the number of tests ignored during the run + */ + public function get ignoreCount():uint + { + return value.ignoreCount; + } + + /** + * @return true if all tests was succeeded + */ + public function get wasSuccessful():Boolean + { + return failureCount == 0; + } + + /** + * Internal use only. + */ + public function createListener():RunListener + { + return new Listener(value); + } + } +} + +import org.libspark.as3unit.runner.notification.RunListener; +import org.libspark.as3unit.runner.Result; +import org.libspark.as3unit.runner.notification.Failure; +import org.libspark.as3unit.runner.Description; +import flash.utils.getTimer; + +class ResultValue +{ + public var count:uint; + public var ignoreCount:uint; + public var failures:Array; + public var runTime:uint; + public var startTime:uint; +} + +class Listener extends RunListener +{ + private var value:ResultValue; + + public function Listener(value:ResultValue) + { + this.value = value; + } + + public override function testRunStarted(description:Description):void + { + value.startTime = getTimer(); + } + + public override function testRunFinished(result:Result):void + { + var endTime:uint = getTimer(); + value.runTime += (endTime - value.startTime); + } + + public override function testStarted(description:Description):void + { + value.count++; + } + + public override function testFailure(failure:Failure):void + { + value.failures.push(failure); + } + + public override function testIgnored(description:Description):void + { + value.ignoreCount++; + } +} Index: /as3/Syndication/trunk/tests/org/libspark/as3unit/runner/manipulation/Sorter.as =================================================================== --- /as3/Syndication/trunk/tests/org/libspark/as3unit/runner/manipulation/Sorter.as (リビジョン 952) +++ /as3/Syndication/trunk/tests/org/libspark/as3unit/runner/manipulation/Sorter.as (リビジョン 952) @@ -0,0 +1,48 @@ +/* + * Copyright(c) 2006 the Spark project. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, + * either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + */ + +package org.libspark.as3unit.runner.manipulation +{ + import org.libspark.as3unit.runner.Description; + import org.libspark.as3unit.runner.Runner; + + /** + * A Sorter orders tests. In general you will not need to use + * a Sorter directly. Instead, use Request.sortWith(Comparator). + */ + public class Sorter implements Comparator + { + private var fComparator:Comparator; + + public function Sorter(comparator:Comparator) + { + fComparator = comparator; + } + + public function apply(runner:Runner):void + { + if (runner is Sortable) { + var sortable:Sortable = Sortable(runner); + sortable.sort(this); + } + } + + public function compare(o1:Description, o2:Description):int + { + return fComparator.compare(o1, o2); + } + } +} Index: /as3/Syndication/trunk/tests/org/libspark/as3unit/runner/manipulation/Filter.as =================================================================== --- /as3/Syndication/trunk/tests/org/libspark/as3unit/runner/manipulation/Filter.as (リビジョン 952) +++ /as3/Syndication/trunk/tests/org/libspark/as3unit/runner/manipulation/Filter.as (リビジョン 952) @@ -0,0 +1,90 @@ +/* + * Copyright(c) 2006 the Spark project. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, + * either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + */ + +package org.libspark.as3unit.runner.manipulation +{ + import org.libspark.as3unit.runner.Description; + import org.libspark.as3unit.runner.Runner; + + /** + * The canonical case of filtering is when you want to run a single test method in a class. + * Rather than introduce runner API just for that one case, AS3Unit provides a general + * filtering mechanism. If you want to filter the tests to be run, extend Filter + * and apply an instance of your filter to the Request before running it + * (see AS3UnitCore.run(request:Request)). + * Alternatively, apply a Filter to a Runner before running + * tests (for exapmle, in conjunction with RunWith + */ + public class Filter + { + /** + * A null Filter that presses all tests through. + */ + public static var ALL:Filter; + + /** + * @param description the description of the test to be run + * @return true if the test should be run + */ + public function shouldRun(description:Description):Boolean + { + throw new DefinitionError('You must override this method.'); + return true; + } + + /** + * Invoke with a Runner to cause all thests it intends to run + * to first be checked with the filter. Only those that pass the filter will be run. + * @param runner the runner to be filtered by the reciver + * @throws NoTestsRemainException if the reciver removes all tests + */ + public function apply(runner:Runner):void + { + if (runner is Filterable) { + var filterable:Filterable = Filterable(runner); + filterable.filter(this); + } + } + + public function get describe():String + { + throw new DefinitionError('You must override this method.'); + return ''; + } + } +} + +import org.libspark.as3unit.runner.manipulation.Filter; +import org.libspark.as3unit.runner.Description; + +class NullFilter extends Filter +{ + public override function shouldRun(description:Description):Boolean + { + return true; + } + + public override function get describe():String + { + return 'all tests'; + } + + private static const initialize:* = staticInitializer(); + private static function staticInitializer():void + { + Filter.ALL = new NullFilter(); + } +} Index: /as3/Syndication/trunk/tests/org/libspark/as3unit/runner/manipulation/Comparator.as =================================================================== --- /as3/Syndication/trunk/tests/org/libspark/as3unit/runner/manipulation/Comparator.as (リビジョン 952) +++ /as3/Syndication/trunk/tests/org/libspark/as3unit/runner/manipulation/Comparator.as (リビジョン 952) @@ -0,0 +1,28 @@ +/* + * Copyright(c) 2006 the Spark project. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, + * either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + */ + +package org.libspark.as3unit.runner.manipulation +{ + import org.libspark.as3unit.runner.Description; + + /** + * Emulate java.util.Comparator + */ + public interface Comparator + { + function compare(o1:Description, o2:Description):int; + } +} Index: /as3/Syndication/trunk/tests/org/libspark/as3unit/runner/manipulation/Filterable.as =================================================================== --- /as3/Syndication/trunk/tests/org/libspark/as3unit/runner/manipulation/Filterable.as (リビジョン 952) +++ /as3/Syndication/trunk/tests/org/libspark/as3unit/runner/manipulation/Filterable.as (リビジョン 952) @@ -0,0 +1,32 @@ +/* + * Copyright(c) 2006 the Spark project. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, + * either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + */ + +package org.libspark.as3unit.runner.manipulation +{ + /** + * Runners that allow filtering should implements this interface. Implement filter() + * to remove tests that don't pass the filter. + */ + public interface Filterable + { + /** + * Remove tests that don't pass filter. + * @param filter the filter to apply + * @throws NoTestsRemainException if all tests are filtered out + */ + function filter(filter:Filter):void; + } +} Index: /as3/Syndication/trunk/tests/org/libspark/as3unit/runner/manipulation/NoTestsRemainException.as =================================================================== --- /as3/Syndication/trunk/tests/org/libspark/as3unit/runner/manipulation/NoTestsRemainException.as (リビジョン 952) +++ /as3/Syndication/trunk/tests/org/libspark/as3unit/runner/manipulation/NoTestsRemainException.as (リビジョン 952) @@ -0,0 +1,25 @@ +/* + * Copyright(c) 2006 the Spark project. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, + * either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + */ + +package org.libspark.as3unit.runner.manipulation +{ + /** + * Thrown when a filter removes all tests from a runner. + */ + public class NoTestsRemainException extends Error + { + } +} Index: /as3/Syndication/trunk/tests/org/libspark/as3unit/runner/manipulation/Sortable.as =================================================================== --- /as3/Syndication/trunk/tests/org/libspark/as3unit/runner/manipulation/Sortable.as (リビジョン 952) +++ /as3/Syndication/trunk/tests/org/libspark/as3unit/runner/manipulation/Sortable.as (リビジョン 952) @@ -0,0 +1,29 @@ +/* + * Copyright(c) 2006 the Spark project. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, + * either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + */ + +package org.libspark.as3unit.runner.manipulation +{ + /** + * Interfaces for runners that allow sorting of tests. By sorting tests based on when they last failed, + * most recently failed first, you can reduce the average time to the first test failing. Test sorting + * should not be used to code with order dependencies between tests. Tests that are isolated from each + * other are less expensive to maintain and can be run individually. + */ + public interface Sortable + { + function sort(sorter:Sorter):void + } +} Index: /as3/Syndication/trunk/tests/org/libspark/as3unit/runner/AS3UnitCore.as =================================================================== --- /as3/Syndication/trunk/tests/org/libspark/as3unit/runner/AS3UnitCore.as (リビジョン 952) +++ /as3/Syndication/trunk/tests/org/libspark/as3unit/runner/AS3UnitCore.as (リビジョン 952) @@ -0,0 +1,161 @@ +/* + * Copyright(c) 2006 the Spark project. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, + * either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + */ + +package org.libspark.as3unit.runner +{ + import org.libspark.as3unit.inter.runners.AsyncHelper; + import org.libspark.as3unit.inter.runners.TextListener; + import org.libspark.as3unit.runner.notification.RunListener; + import org.libspark.as3unit.runner.notification.RunNotifier; + import org.libspark.asunit.framework.Test; + import org.libspark.as3unit.inter.runners.OldTestClassRunner; + + /** + * AS3UnitCore is a facade for running tests. It supports running AS3Unit tests, + * ASUnit tests, and mixtures. For one-shot test runs, use the static method main(...classes). + * If you want to add special runners, create an instance of AS3UnitCore first + * and use it to run the tests. + * + * @see org.libspark.as3unit.runner.Result + * @see org.libspark.as3unit.runner.notification.RunListener + * @see org.libspark.as3unit.runner.Request + */ + public class AS3UnitCore + { + private var notifier:RunNotifier; + + /** + * Create a new AS3UnitCore to run tests. + */ + public function AS3UnitCore() + { + notifier = new RunNotifier(); + } + + /** + * Run the tests contained in classes. Write feedback while the tests + * are running and write stack traces for all failed tests after all tests complete. + * @param classes Classes in which to find tests + * @return a Result describing the details of the test run and the failed tsts + */ + public static function main(...classes:Array):void + { + new AS3UnitCore().runMain(classes); + } + + public static function classes(...classes:Array):Result + { + var core:AS3UnitCore = new AS3UnitCore(); + return core.runClasses.apply(core, classes); + } + + /** + * Do not use. Testing purposes only. + */ + public function runMain(classes:Array):Result + { + addListener(new TextListener()); + return runClasses.apply(this, classes); + } + + /** + * Run all the tsts in classes. + * @param classes the classes containing tests + * @return a Result describing the details of the test run and the failed tests + */ + public function runClasses(...classes:Array):Result + { + return run(Request.classes('All', classes)); + } + + /** + * Run all the tests containing in Request. + * @param request the request describing tests. + * @return a Result describing the details of the test run and the failed tests + */ + public function run(request:Request):Result + { + return runWithRunner(request.getRunner()); + } + + /** + * Run all the tests contained in ASUnit test. Here for backward compatibillity. + * @param test the old-style test + * @return a Result describing the details of the test run and the failed tests + */ + public function runOldTest(test:org.libspark.asunit.framework.Test):Result + { + return runWithRunner(new OldTestClassRunner(test)); + } + + /** + * Do not use. Testing purposes only. + */ + public function runWithRunner(runner:Runner):Result + { + var result:Result = new Result(); + var listener:RunListener = result.createListener(); + var needRemoveListener:Boolean = true; + var description:Description = runner.description; + addFirstListener(listener); + try { + notifier.fireTestRunStarted(runner.description); + runner.run(notifier); + if (!runner.hasFinised) { + runner.addCallback(function():void + { + notifier.fireTestRunFinished(result); + removeListener(listener); + }); + needRemoveListener = false; + } + else { + notifier.fireTestRunFinished(result); + } + } + finally { + if (needRemoveListener) { + removeListener(listener); + } + } + return result; + } + + private function addFirstListener(listener:RunListener):void + { + notifier.addFirstListener(listener); + } + + /** + * Add a listener to be notified as the tests run. + * @param listener the listener + * @see org.libspark.as3unit.runner.notification.RunListener + */ + public function addListener(listener:RunListener):void + { + notifier.addListener(listener); + } + + /** + * Remove a listener + * @param listener the listener to remove + */ + public function removeListener(listener:RunListener):void + { + notifier.removeListener(listener); + } + } +} Index: /as3/Syndication/trunk/tests/org/libspark/as3unit/runner/Description.as =================================================================== --- /as3/Syndication/trunk/tests/org/libspark/as3unit/runner/Description.as (リビジョン 952) +++ /as3/Syndication/trunk/tests/org/libspark/as3unit/runner/Description.as (リビジョン 952) @@ -0,0 +1,172 @@ +/* + * Copyright(c) 2006 the Spark project. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, + * either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + */ + +package org.libspark.as3unit.runner +{ + import flash.utils.getQualifiedClassName; + + /** + * A Description describes a test which is to be run or has been run. + * Descriptions can be atomic (a single test) or compound (containing + * children tests). Descrptions are used to provide feedback about the + * tests that are about to run (for example, the tree view visible in many IDEs) or + * tests that have been run (for example, the failure view). + * Descriptions are implemented as a single class rather than a Composite + * because they are enterely infomational. They contain no logic aside from counting + * ther tests. + * In the past, we used the raw asunit.framework.TestCase and + * asunit.framework.TestSuites to display the tree of tests. This was no + * longer visible in AS3Unit because atomic tests no longer have a superclass below + * Object. + * We needed a way to pass a class and name together. Description emeged from this. + * + * @see org.libspark.as3unit.runner.Request + * @see org.libspark.as3unit.runner.Runner + */ + public class Description + { + /** + * Create a Descritpion named name. + * Generaly, you will add children to this Description. + * @param name The name of the Decription + * @return A Description named name + */ + public static function createSuiteDescription(name:String):Description + { + return new Description(name); + } + + /** + * Create a Description of a single test named name + * in the class clazz. + * Generaly, this will be leaf Description. + * @param clazz The class of the test + * @param name The name of the test (a method name for test declared with test) + * @return A Description named name + */ + public static function createTestDescription(clazz:Class, name:String):Description + { + return new Description(name + "(" + getQualifiedClassName(clazz) + ")"); + } + + /** + * Create a generice Descritpion that says there are tests in testClass. + * This is used as a last resort when you cannot precisely describe the individual tests in the class. + * @param testClass A Class containing tests + * @param A Description or testClass + */ + public static function createTestSuiteDescription(testClass:Class):Description + { + return new Description(getQualifiedClassName(testClass)); + } + + public static var EMPTY:Description = new Description("No Tests"); + public static var TEST_MECHANISM:Description = new Description("Test mechanism"); + + private var fChildren:Array; + private var fDisplayName:String; + + public function Description(displayName:String) + { + fChildren = new Array(); + fDisplayName = displayName; + } + + /** + * @return a user-understandable label + */ + public function get displayName():String + { + return fDisplayName; + } + + /** + * Add description as a child of the reciver. + * @param description The soon-to-be child. + */ + public function addChild(description:Description):void + { + children.push(description); + } + + /** + * @return the reciver's children, if any + */ + public function get children():Array + { + return fChildren; + } + + /** + * @return true if the receiver is a suite + */ + public function get isSuite():Boolean + { + return !isTest; + } + + /** + * @return true if the receiver is an atomic test + */ + public function get isTest():Boolean + { + return children.length == 0; + } + + /** + * @returns the total number of atomic tests in the receiver + */ + public function get testCount():uint + { + if (isTest) { + return 1; + } + var result:uint = 0; + for each (var child:Description in children) { + result += child.testCount; + } + return result; + } + + public function equals(obj:*):Boolean + { + if (!(obj is Description)) { + return false; + } + var d:Description = Description(obj); + if (displayName != d.displayName) { + return false; + } + var c1:Array = children; + var c2:Array = d.children; + if (c1.length != c2.length) { + return false; + } + var len:uint = c1.length; + for (var i:uint = 0; i < len; ++i) { + if (!(Description(c1[i]).equals(c2[i]))) { + return false; + } + } + return true; + } + + public function toString():String + { + return displayName; + } + } +} Index: /as3/Syndication/trunk/tests/org/libspark/as3unit/runner/notification/RunNotifier.as =================================================================== --- /as3/Syndication/trunk/tests/org/libspark/as3unit/runner/notification/RunNotifier.as (リビジョン 952) +++ /as3/Syndication/trunk/tests/org/libspark/as3unit/runner/notification/RunNotifier.as (リビジョン 952) @@ -0,0 +1,172 @@ +/* + * Copyright(c) 2006 the Spark project. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, + * either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + */ + +package org.libspark.as3unit.runner.notification +{ + import org.libspark.as3unit.runner.Description; + import org.libspark.as3unit.runner.Result; + + /** + * If you write custom runners, you may need to notify AS3Unit of your progress running tests. + * Do this by invoking the RunNotifier passed to your implementation of + * Runner.run(notifier:RunNotifier). Future evolution of this class is likely to + * move fireTestRunStarted() and fireTestRunFinished() + * to a separate class since they should only be called once per run. + */ + public class RunNotifier + { + private var listeners:Array; + private var fPleaseStop:Boolean; + + public function RunNotifier() + { + listeners = new Array(); + fPleaseStop = false; + } + + /** + * Internal use only + */ + public function addListener(listener:RunListener):void + { + listeners.push(listener); + } + + /** + * Internal use only + */ + public function removeListener(listener:RunListener):void + { + var listeners_:Array = listeners; + var len:uint = listeners_.length; + for (var i:uint = 0; i < len; ++i) { + if (listeners_[i] == listener) { + listeners_.splice(i, 1); + return; + } + } + } + + private function notifyListener(operation:Function):void + { + var listeners_:Array = listeners; + var len:uint = listeners_.length; + for (var i:uint = 0; i < len;) { + try { + operation(listeners_[i]); + ++i; + } + catch (e:Error) { + listeners_.splice(i, 1); + len = listeners_.length; + fireTestFailure(new Failure(Description.TEST_MECHANISM, e)); + } + } + } + + /** + * Do not invoke. + */ + public function fireTestRunStarted(description:Description):void + { + notifyListener(function(each:RunListener):void { + each.testRunStarted(description); + }); + } + + /** + * Do not invoke. + */ + public function fireTestRunFinished(result:Result):void + { + notifyListener(function(each:RunListener):void { + each.testRunFinished(result); + }); + } + + /** + * Invoke to tell listeners that an atomic test is about to start. + * @param description the description of the atomic test (generally a class and method name) + * @throws StoppedByUserException thrown if a user has requested that the test run stop + */ + public function fireTestStarted(description:Description):void + { + if (fPleaseStop) { + throw new StoppedByUserException(); + } + notifyListener(function(each:RunListener):void { + each.testStarted(description); + }); + } + + /** + * Invoke to tell listeners that an atomic test failed. + * @param failure the description of the test that failed and the exception thrown + */ + public function fireTestFailure(failure:Failure):void + { + notifyListener(function(each:RunListener):void { + each.testFailure(failure); + }); + } + + /** + * Invoke to tell listeners that an atomic test was igonred. + * @param description the description of the ignored test + */ + public function fireTestIgnored(description:Description):void + { + notifyListener(function(each:RunListener):void { + each.testIgnored(description); + }); + } + + /** + * Invoke to tell listeners that an atomic test finished. Always invoke fireTestFinished() + * if you invoke fireTestStarted() as listeners are likely to expect them to come in pairs. + * @param description the description of the test that finished. + */ + public function fireTestFinished(description:Description):void + { + notifyListener(function(each:RunListener):void { + each.testFinished(description); + }); + } + + /** + * Ask that the tests run stop before starting the next test. Phrased polltely because + * the test currently running will not be interrupted. It seems a little odd to put this + * functionality here, but the RunNotifier is the only object guranteed + * to be shared amongst the many runners invoked. + */ + public function pleaseStop():void + { + fPleaseStop = true; + } + + public function addFirstListener(listener:RunListener):void + { + listeners.unshift(listener); + } + + public function testAborted(description:Description, cause:Object):void + { + fireTestStarted(description); + fireTestFailure(new Failure(description, cause)); + fireTestFinished(description); + } + } +} Index: /as3/Syndication/trunk/tests/org/libspark/as3unit/runner/notification/Failure.as =================================================================== --- /as3/Syndication/trunk/tests/org/libspark/as3unit/runner/notification/Failure.as (リビジョン 952) +++ /as3/Syndication/trunk/tests/org/libspark/as3unit/runner/notification/Failure.as (リビジョン 952) @@ -0,0 +1,97 @@ +/* + * Copyright(c) 2006 the Spark project. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, + * either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + */ + +package org.libspark.as3unit.runner.notification +{ + import org.libspark.as3unit.runner.Description; + + /** + * A Failure holds a description of the failed test and the + * exception that was thrown while running it. In most cases the Description + * will be of a single test. However, if problems are encountered while constructing the + * test (for example, if a beforeClass method is not static). It may describe + * something other than a single test. + */ + public class Failure + { + private var fDescription:Description; + private var fThrownException:Object; + + /** + * Constructs a Failure with the given description and exception. + * @param description a Description of the test that failed. + * @param thrownException the exception that was thrown while running the test. + */ + public function Failure(description:Description, thrownException:Object) + { + fThrownException = thrownException; + fDescription = description; + } + + /** + * @return a user-understandable label for the test + */ + public function get testHeader():String + { + return fDescription.displayName; + } + + /** + * @return the raw description of the context of the failure. + */ + public function get description():Description + { + return fDescription; + } + + /** + * @return the exception thrown + */ + public function get exception():Object + { + return fThrownException; + } + + public function toString():String + { + return testHeader + ": " + message; + } + + /** + * Convenience method + * @return the printed from of the exception + */ + public function get trace():String + { + if (exception is Error) { + return exception.getStackTrace(); + } + return ''; + } + + /** + * Convenience method + * @return the message of the thrown exception + */ + public function get message():String + { + if (exception is Error) { + return exception.message; + } + return ''; + } + } +} Index: /as3/Syndication/trunk/tests/org/libspark/as3unit/runner/notification/StoppedByUserException.as =================================================================== --- /as3/Syndication/trunk/tests/org/libspark/as3unit/runner/notification/StoppedByUserException.as (リビジョン 952) +++ /as3/Syndication/trunk/tests/org/libspark/as3unit/runner/notification/StoppedByUserException.as (リビジョン 952) @@ -0,0 +1,28 @@ +/* + * Copyright(c) 2006 the Spark project. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, + * either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + */ + +package org.libspark.as3unit.runner.notification +{ + /** + * Thrown when a user rhas requested that the test run stop. + * Writers of test running GUIs should be prepared to catch a StoppedByUserException + * + * @see org.libspark.as3unit.runner.notification.RunNotifier + */ + public class StoppedByUserException extends Error + { + } +} Index: /as3/Syndication/trunk/tests/org/libspark/as3unit/runner/notification/RunListener.as =================================================================== --- /as3/Syndication/trunk/tests/org/libspark/as3unit/runner/notification/RunListener.as (リビジョン 952) +++ /as3/Syndication/trunk/tests/org/libspark/as3unit/runner/notification/RunListener.as (リビジョン 952) @@ -0,0 +1,98 @@ +/* + * Copyright(c) 2006 the Spark project. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, + * either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + */ + +package org.libspark.as3unit.runner.notification +{ + import org.libspark.as3unit.runner.Description; + import org.libspark.as3unit.runner.Result; + + /** + * If you need to respond to the events during a test run, extend RunListener + * and override the apporiate methods. If a listener throws an exception while processing a + * test event, it will be removed for the remainder of the test run. + * + * For example, suppose you have a Cowbell + * class that you want to makes a noise whenever a test fails. You could wirte: + * + * public class RingingListener extends RunListener { + * public override function testFailure(failure:Failure):void { + * Cowbell.ring(); + * } + * } + * + * + * To invoke your listener, you need to run your tests throwugh AS3UnitCore. + * + * var core:AS3UnitCore = new AS3UnitCore(); + * core.addListener(new RingingListener()); + * core.runClasses(MyTestClass); + * + * + * @see org.libspark.as3unit.runner.AS3UnitCore + */ + import org.libspark.as3unit.runner.Description; + + public class RunListener + { + /** + * Called before any tests have been run. + * @param description describes the tests to be run + */ + public function testRunStarted(description:Description):void + { + } + + /** + * Called when all tests have finished + * @param result the summary of the test run. Including all the tests that failed. + */ + public function testRunFinished(result:Result):void + { + } + + /** + * Called when an atomic test is about to be started. + * @param description the description of the test that is about to be run (generally a class and method name) + */ + public function testStarted(description:Description):void + { + } + + /** + * Called when an atomic test has finished, whether the test succseds or fails. + * @param description the description of the test that just ran + */ + public function testFinished(description:Description):void + { + } + + /** + * Called when an atomic test fails. + * @param failure describes the test that failed and the exception that was thrown + */ + public function testFailure(failure:Failure):void + { + } + + /** + * Called when a test will not be run. + * @param description describes the test that will not be run + */ + public function testIgnored(description:Description):void + { + } + } +} Index: /as3/Syndication/trunk/tests/org/libspark/as3unit/runner/Request.as =================================================================== --- /as3/Syndication/trunk/tests/org/libspark/as3unit/runner/Request.as (リビジョン 952) +++ /as3/Syndication/trunk/tests/org/libspark/as3unit/runner/Request.as (リビジョン 952) @@ -0,0 +1,143 @@ +/* + * Copyright(c) 2006 the Spark project. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, + * either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + */ + +package org.libspark.as3unit.runner +{ + import org.libspark.as3unit.inter.requests.ClassRequest; + import org.libspark.as3unit.inter.requests.ClassesRequest; + import org.libspark.as3unit.inter.requests.ErrorReportingRequest; + import org.libspark.as3unit.inter.requests.FilterRequest; + import org.libspark.as3unit.inter.requests.SortingRequest; + import org.libspark.as3unit.runner.manipulation.Filter; + import org.libspark.as3unit.runner.manipulation.Comparator; + import org.libspark.as3unit.runner.Description; + import org.libspark.as3unit.runner.Description; + import org.libspark.as3unit.runner.Description; + + /** + * A Request is an abstract description of tests to be run. Older version of + * AS3Unit did not need such a concept-tests to be run were desribed either by classes containing + * tests or a tree of Tests. Howerver, we want to support filtering and sorting. + * so we need a more abstract specification then the tests themselves and a richer + * specification then just the classes. + * + * The flow when AS3Unit runs tests is tat a Request specifies some tests to be run -> + * a Runner is created for each class implled by the Request -> + * the Runner retruns a detailed Description which is a tree structure of + * the tests to be run. + */ + public class Request + { + /** + * Create a Request that, when processed, will run a single test. + * This is done by filtering out all other tests. This method is used to support returning + * single tests. + * @param clazz the class of the test + * @param methodName the name of the test + * @return a Request that will cause a single test be run + */ + public static function method(clazz:Class, methodName:String):Request + { + var method:Description = Description.createTestDescription(clazz, methodName); + return Request.aClass(clazz).filterWithDescription(method); + } + + /** + * Create a Request that, when processed, will run all the tests + * in a class. The odd name is necessary because class is a reserved word. + * @param clazz the class containg the tests + * @return a Request that will cause all tests in the class to be run + */ + public static function aClass(clazz:Class):Request + { + return new ClassRequest(clazz); + } + + /** + * Create a Request that, when processed, will run all the tests + * in a set of classes. + * @param collectionName a name to identify this suite of tests + * @param classes the classes containing the tests + * @return a Request that will cause all tests in the classes to be run + */ + public static function classes(collectionName:String, classes:Array):Request + { + return new ClassesRequest(collectionName, classes); + } + + public static function errorReport(klass:Class, cause:Object):Request + { + return new ErrorReportingRequest(klass, cause); + } + + public function getRunner():Runner + { + throw new SyntaxError('You must override this method.'); + return null; + } + + public function filterWith(filter:Filter):Request + { + return new FilterRequest(this, filter); + } + + public function filterWithDescription(desiredDescription:Description):Request + { + return filterWith(new DescriptionFilter(desiredDescription)); + } + + public function sortWith(comparator:Comparator):Request + { + return new SortingRequest(this, comparator); + } + + public static function classWithoutSuiteMethod(newTestClass:Class):Request + { + return new ClassRequest(newTestClass, false); + } + } +} + +import org.libspark.as3unit.runner.manipulation.Filter; +import org.libspark.as3unit.runner.Description; + +class DescriptionFilter extends Filter +{ + private var desiredDescription:Description; + + public function DescriptionFilter(description:Description) + { + desiredDescription = description; + } + + public override function shouldRun(description:Description):Boolean + { + if (description.isTest) { + return desiredDescription.equals(description); + } + for each (var child:Description in description.children) { + if (shouldRun(child)) { + return true; + } + } + return false; + } + + public override function get describe():String + { + return "Method " + desiredDescription.displayName; + } +} Index: /as3/Syndication/trunk/tests/org/libspark/as3unit/runner/Runner.as =================================================================== --- /as3/Syndication/trunk/tests/org/libspark/as3unit/runner/Runner.as (リビジョン 952) +++ /as3/Syndication/trunk/tests/org/libspark/as3unit/runner/Runner.as (リビジョン 952) @@ -0,0 +1,116 @@ +/* + * Copyright(c) 2006 the Spark project. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, + * either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + */ + +package org.libspark.as3unit.runner +{ + import org.libspark.as3unit.runner.notification.RunNotifier; + + /** + * A Runner runs tests and notifies a RunNotifier + * of signifciant events as it does so. You will need subclass Runner + * when using RunWith to invoke a custom runner. When creating + * a custom runner, in addition to implementing the abstract method here you must + * also provide a constructor that takes as an argument the Class containing + * the tests. + * + * @see org.libspark.as3unit.runner.Description + */ + public class Runner + { + private var finished:Boolean = false; + private var callbacks:Array = []; + + /** + * @return a Description showing the tests to be run by the reciver. + */ + public function get description():Description + { + throw new DefinitionError('You must override this method.'); + return null; + } + + /** + * Run the tests for this runner. + * @param notifier will be notified or events while tests are being run-tests + * being started, finishing, and failing + */ + public function run(notifier:RunNotifier):void + { + throw new DefinitionError('You must override this method.'); + } + + /** + * @return the number of tests to be run by the receiver + */ + public function get testCount():uint + { + return description.testCount; + } + + /** + * @return true if Runner.run has finished. + */ + public function get hasFinised():Boolean + { + return finished; + } + + /** + * Add callback for run complete. + * + * @param callback + */ + public function addCallback(callback:Function):void + { + callbacks.push(callback); + if (finished) { + callback(); + } + } + + /** + * Remove callback. + * + * @param callback + */ + public function removeCallback(callback:Function):void + { + var index:int = callbacks.indexOf(callback); + if (index != -1) { + callbacks.splice(index, 1); + } + } + + /** + * Begin run process. + */ + protected function start():void + { + finished = false; + } + + /** + * End run process. + */ + protected function finish():void + { + finished = true; + for each (var callback:Function in callbacks) { + callback(); + } + } + } +} Index: /as3/Syndication/trunk/tests/org/libspark/as3unit/beforeClass.as =================================================================== --- /as3/Syndication/trunk/tests/org/libspark/as3unit/beforeClass.as (リビジョン 952) +++ /as3/Syndication/trunk/tests/org/libspark/as3unit/beforeClass.as (リビジョン 952) @@ -0,0 +1,42 @@ +/* + * Copyright(c) 2006 the Spark project. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, + * either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + */ + +package org.libspark.as3unit +{ + /** + * Sometimes several tests need to share computationally expensive setup + * (like logging int oa database). While this compromise the independence of + * tests, sometimes it is a necessary optimization. Declaring a static void no-arg method + * with beforeClass namespace it to be run once before any of + * the test method in the class. + * + * For example: + * + * + * public class Example { + * beforeClass static function onlyOnce():void { + * ... + * } + * test function tests():void { + * ... + * } + * } + * + * + * @see org.libspark.as3unit.afterClass + */ + public namespace beforeClass = 'http://as3unit.libspark.org/beforeClass'; +} Index: /as3/Syndication/trunk/tests/org/libspark/as3unit/runners/parameters.as =================================================================== --- /as3/Syndication/trunk/tests/org/libspark/as3unit/runners/parameters.as (リビジョン 952) +++ /as3/Syndication/trunk/tests/org/libspark/as3unit/runners/parameters.as (リビジョン 952) @@ -0,0 +1,23 @@ +/* + * Copyright(c) 2006 the Spark project. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, + * either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + */ + +package org.libspark.as3unit.runners +{ + /** + * @see org.libspark.as3unit.runners.Parameterized + */ + public namespace parameters = 'http://as3unit.libspark.org/parameters'; +} Index: /as3/Syndication/trunk/tests/org/libspark/as3unit/runners/parameters_injection.as =================================================================== --- /as3/Syndication/trunk/tests/org/libspark/as3unit/runners/parameters_injection.as (リビジョン 952) +++ /as3/Syndication/trunk/tests/org/libspark/as3unit/runners/parameters_injection.as (リビジョン 952) @@ -0,0 +1,23 @@ +/* + * Copyright(c) 2006 the Spark project. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, + * either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + */ + +package org.libspark.as3unit.runners +{ + /** + * @see org.libspark.as3unit.runners.Parameterized + */ + public namespace parameters_injection = 'http://as3unit.libspark.org/parameters_injection'; +} Index: /as3/Syndication/trunk/tests/org/libspark/as3unit/runners/Suite.as =================================================================== --- /as3/Syndication/trunk/tests/org/libspark/as3unit/runners/Suite.as (リビジョン 952) +++ /as3/Syndication/trunk/tests/org/libspark/as3unit/runners/Suite.as (リビジョン 952) @@ -0,0 +1,57 @@ +/* + * Copyright(c) 2006 the Spark project. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, + * either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + */ + +package org.libspark.as3unit.runners +{ + import org.libspark.as3unit.inter.runners.InitializationError; + import org.libspark.as3unit.inter.runners.TestClassRunner; + import org.libspark.as3unit.runner.Request; + + import flash.utils.getQualifiedClassName; + + /** + * Using Suite as a runner allows you to manually + * build a suite containing tests from many classes. It is the AS3Unit equivalent of the ASUnit + * static org.libspark.asunit.framework.Test suite() method. To use it, annotate + * class with public static const RunWith:Class = Suite; and + * public static const SuiteClasses:Array = [TestClass1, ...];. + * When you run this class, It will run all the tests in all the suite classes. + */ + public class Suite extends TestClassRunner + { + /** + * Internal use only. + */ + public function Suite(klass:Class, annotatedClasses:Array=null) + { + if (annotatedClasses == null) { + annotatedClasses = getAnnotatedClasses(klass); + } + super(klass, Request.classes(getQualifiedClassName(klass), annotatedClasses).getRunner()); + } + + private static function getAnnotatedClasses(klass:Class):Array + { + if (!('SuiteClasses' in klass)) { + throw InitializationError.createWithString("class '" + getQualifiedClassName(klass) + "' must have a SuiteClasses annotation"); + } + if (!(klass.SuiteClasses is Array)) { + throw InitializationError.createWithString("SuiteClasses annotation must be Array in class '" + getQualifiedClassName(klass) + "'"); + } + return klass.SuiteClasses; + } + } +} Index: /as3/Syndication/trunk/tests/org/libspark/as3unit/runners/AllTests.as =================================================================== --- /as3/Syndication/trunk/tests/org/libspark/as3unit/runners/AllTests.as (リビジョン 952) +++ /as3/Syndication/trunk/tests/org/libspark/as3unit/runners/AllTests.as (リビジョン 952) @@ -0,0 +1,54 @@ +/* + * Copyright(c) 2006 the Spark project. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, + * either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + */ + +package org.libspark.as3unit.runners +{ + import org.libspark.asunit.framework.Test; + import org.libspark.as3unit.inter.runners.OldTestClassRunner; + + /** + * Runner for use with ASUnit-style AllTests classes + * (those that only implement a static suite() + * method). For example: + * + * public class ProductTests { + * public static const RunWith:Class = AllTests; + * public statc function suite():org.libspark.asunit.framework.Test { + * ... + * } + * } + * + */ + public class AllTests extends OldTestClassRunner + { + public function AllTests(klass:Class) + { + super(testFromSuiteMethod(klass)); + } + + public static function testFromSuiteMethod(klass:Class):Test + { + var suite:Test = null; + try { + suite = klass["suite"](); + } + catch (e:Error) { + throw new Error("Can not invoke " + klass + ".suite()"); + } + return suite; + } + } +} Index: /as3/Syndication/trunk/tests/org/libspark/as3unit/runners/Parameterized.as =================================================================== --- /as3/Syndication/trunk/tests/org/libspark/as3unit/runners/Parameterized.as (リビジョン 952) +++ /as3/Syndication/trunk/tests/org/libspark/as3unit/runners/Parameterized.as (リビジョン 952) @@ -0,0 +1,159 @@ +/* + * Copyright(c) 2006 the Spark project. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, + * either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + */ + +package org.libspark.as3unit.runners +{ + import org.libspark.as3unit.inter.runners.CompositeRunner; + import org.libspark.as3unit.inter.runners.MethodValidator; + import org.libspark.as3unit.inter.runners.TestClassMethodsRunner; + import org.libspark.as3unit.inter.runners.TestClassRunner; + import org.libspark.as3unit.inter.runners.TestClassRunner; + import org.libspark.as3unit.inter.runners.InitializationError; + + /** + * The custom runner Parameterized implements parameterized + * tests. When running a parameterizaed test class, instance are created for the + * cross-product of the test methods and the test data elements. + * + * For example, to test a Fibonacci function, write + * + * public class FibonnaciTest { + * public static const RunWith:Class = Parameterized; + * parameters static function date():Array { + * return [[0, 0], [1, 2], [2, 1], [3, 2], [4, 3], [5, 5], [6, 8]]; + * } + * private var input:uint; + * private var expected:uint; + * parameters_injection function initialize(input:uint, expected:uint) { + * this.input = input; + * this.expected = expected; + * } + * test function test():void { + * assertEquals(expected, Fibonacci.compute(input)); + * } + * } + * + * Each instance of FibonacciTest will be constructed using + * two-argument parameter_injection method and the date values in + * parameters method. + */ + public class Parameterized extends TestClassRunner + { + public static function eachOne(...params:Array):Array + { + var results:Array = new Array(); + for each (var param:Object in params) { + results.push([param]); + } + return results; + } + + public function Parameterized(klass:Class) + { + super(klass, new RunAllParameterMethods(klass)); + } + + protected override function validate(methodValidator:MethodValidator):void + { + methodValidator.validateStaticMethods(); + methodValidator.validateInstanceMethods(); + } + } +} + +import org.libspark.as3unit.inter.runners.TestClassMethodsRunner; +import org.libspark.as3unit.inter.runners.Method; +import org.libspark.as3unit.inter.runners.CompositeRunner; +import org.libspark.as3unit.assert.fail; + +import org.libspark.as3unit.runners.parameters; +import org.libspark.as3unit.runners.parameters_injection; + +import flash.utils.getQualifiedClassName; + +class TestClassRunnerForParameters extends TestClassMethodsRunner +{ + private var parameters:Array; + private var parameterSetNumber:uint; + private var injectMethod:Method; + + public function TestClassRunnerForParameters(klass:Class, parameters:Array, i:uint) + { + super(klass); + this.parameters = parameters; + this.parameterSetNumber = i; + injectMethod = getInjectMethod(); + } + + protected override function createTest():Object + { + var test:Object = super.createTest(); + injectMethod.invoke(test, parameters); + return test; + } + + protected override function get name():String + { + return '[' + parameterSetNumber + ']'; + } + + protected override function testName(method:Method):String + { + return method.name + '[' + parameterSetNumber + ']'; + } + + private function getInjectMethod():Method + { + for each (var method:Method in Method.getDeclaredMethods(testClass)) { + if (method.namespace.uri == parameters_injection.uri) { + return method; + } + } + throw new Error('No parameter injection method on class ' + getQualifiedClassName(testClass)); + } +} + +class RunAllParameterMethods extends CompositeRunner +{ + private var klass:Class; + + public function RunAllParameterMethods(klass:Class) + { + super(getQualifiedClassName(klass)); + this.klass = klass; + var i:uint = 0; + for each (var parameters:Array in getParametersList()) { + super.add(new TestClassRunnerForParameters(klass, parameters, i++)); + } + } + + private function getParametersList():Array + { + return getParametersMethod().invoke(null); + } + + private function getParametersMethod():Method + { + for each (var method:Method in Method.getDeclaredMethods(klass)) { + if (method.isStatic) { + if (method.namespace.uri == parameters.uri) { + return method; + } + } + } + throw new Error('No public static parameters method on class ' + name); + } +} Index: /as3/Syndication/trunk/src/org/libspark/syndication/RSSFeedEntry.as =================================================================== --- /as3/Syndication/trunk/src/org/libspark/syndication/RSSFeedEntry.as (リビジョン 951) +++ /as3/Syndication/trunk/src/org/libspark/syndication/RSSFeedEntry.as (リビジョン 952) @@ -5,4 +5,5 @@ import org.libspark.syndication.namespaces.dc; import org.libspark.syndication.namespaces.content; + import org.libspark.syndication.utils.DateUtil; use namespace rss; @@ -65,5 +66,5 @@ if (_published == null && !!_data.dc::date.toString()) { - _published = Feed.parseW3CDate(_data.dc::date.toString()); + _published = DateUtil.parseW3C(_data.dc::date.toString()); } return _published; Index: /as3/Syndication/trunk/src/org/libspark/syndication/utils/DateUtil.as =================================================================== --- /as3/Syndication/trunk/src/org/libspark/syndication/utils/DateUtil.as (リビジョン 952) +++ /as3/Syndication/trunk/src/org/libspark/syndication/utils/DateUtil.as (リビジョン 952) @@ -0,0 +1,142 @@ +package org.libspark.syndication.utils +{ + public class DateUtil + { + public static const MILLISECOND:Number = 1; + public static const SECOND:Number = MILLISECOND * 1000; + public static const MINUTE:Number = SECOND * 60; + public static const HOUR:Number = MINUTE * 60; + public static const DAY:Number = HOUR * 24; + + /** + * day names map. + */ + public static const DAY_NAMES_SHORT:Array = [ + 'Mon', 'Tue', 'Wed', 'Thu', + 'Fri','Sat', 'Sun' + ]; + + /** + * month name map. (short) + */ + public static const MONTH_NAMES_SHORT:Array = [ + 'Jan', 'Feb', 'Mar', + 'Apr', 'May', 'Jun', + 'Jul', 'Aug', 'Sep', + 'Oct', 'Nov', 'Dec' + ]; + + /** + * month name map. (long) + */ + public static const MONTH_NAMES_LONG:Array = [ + 'January', 'Febrary', 'March', + 'April', 'May', 'June', + 'July', 'August', 'September', + 'October', 'November', 'December' + ]; + + /** + * timezone map. + */ + public static const TIMEZONES:Object = { + 'ADT': -3 * HOUR, + 'AST': -4 * HOUR, + 'CDT': -5 * HOUR, + 'CST': -6 * HOUR, + 'EDT': -4 * HOUR, + 'EST': -5 * HOUR, + 'GMT': 0, + 'MDT': -6 * HOUR, + 'MST': -7 * HOUR, + 'PDT': -7 * HOUR, + 'PST': -8 * HOUR, + 'UT': 0, + 'UTC': 0, + 'Z': 0, + 'A': -1 * HOUR, + 'M': -12 * HOUR, + 'N': 1 * HOUR, + 'Y': 12 * HOUR + } + + public static function parseRFC822(dateString:String):Date + { + var parts:Array = dateString.split(' '); + var dayNames:Array = DAY_NAMES_SHORT.map(function (...a):* { return a[0].toLowerCase(); }); + + var dn:String = parts[0].toLowerCase(); + var dl:int = dn.length - 1; + if ([',', '.'].indexOf(d