2011年9月24日土曜日

JUnitのRuleパッケージについて調査

最近JUnit 4.9がリリースされました。
ClassRule,TestRuleの変更がありました。
TestWatchmanがdeprecatedになってTestWatcherに置き換わるなど。

Ruleのパッケージについて、あまり知らなかったので、調べて、まとめてみました。


TestName
現在のテストメソッドの情報等を取得する。

public class SampleClassTest {
 @Rule
 public TestName name = new TestName();
 @Test
 public void test() {
  System.out.println(name.getMethodName());
  fail("Not yet implemented");
        }
}

ErrorCollector
読んで字の通り、例外を集めて保持するクラスです。例外をaddして、最後のverifyでaddされたエラーの個数などでチェックをかけます。

public class TestExternalResource {
 @Rule
 public ErrorCollector collector = new ErrorCollector() {
  protected void verify() throws Throwable {

   System.out.println("[ErrorCollector]");
   super.verify();
  };
 };

 @Test
 public void test() {
  collector.addError(new Throwable("first thing went wrong"));
  collector.addError(new Throwable("second thing went wrong"));
  int sample = 1;
  collector.checkThat(0, is(sample));

 }
}

ExpectedException
例外を制御する構文です。@Test(expected=NullPointerException.class)と同じような意味ですが、もうちょっと
拡張性を高くしたい場合に使えます。

public class TestExpectedException {
 @Rule
 public ExpectedException thrown = ExpectedException.none();

 @Test
 public void throwsNothing() {
  // no exception expected, none thrown: passes.
 }

 @Test
 public void throwsNullPointerException() {
  thrown.expect(NullPointerException.class);
  throw new NullPointerException();
 }

 @Test
 public void throwsNullPointerExceptionWithMessage() {
  Matcher[] allowedExceptionMatchers = {
    is(NullPointerException.class),
    is(IllegalArgumentException.class) };
  thrown.expect(anyOf(allowedExceptionMatchers));
  thrown.expectMessage("happened?");
  throw new NullPointerException("What happened?");
 }

}

TemporaryFolder
/tmp以下にファイルやディレクトリをおく場合に使えるクラスです。

public class TestTemporaryFolder {
 @Rule
 public TemporaryFolder folder = new TemporaryFolder();

 @Test
 public void test() throws IOException {
  File createFile = folder.newFile("myFile.txt");
  File createFolder = folder.newFolder("subFolder");
  System.out.println("Path:" + createFile.getAbsolutePath());
  System.out.println("Path:" + createFolder.getAbsolutePath());
 }

}


Timeout
メソッドのタイムアウト監視クラスです。メソッドの実行時間のチェック等に使います。

public class TestTimeout {
 @Rule
 public MethodRule globalTimeout = new Timeout(1000);

 @Test
 public void test() {
  for (;;)
   ;
 }

}


Verifier
テストが成功した後に、チェックする仕組みを入れたい場合このクラスを利用します。

public class TestVerifier {
 private ErrorLog error = new ErrorLog();

 @Rule
 public MethodRule verifier = new Verifier() {
  @Override
  public void verify() {
   System.out.println("[Verifier]");
   assertTrue(error.isEmpty());
  }
 };
 @Test
 public void test() {
  fail("Not yet implemented");
 }

 @Test
 public void test2() {
  error.add("sample");
 }
}



TestWatchman(TestWatcher)
テストケースの結果をテスト実施後すぐに確認したい場合に使えます。
public class TestTestWachman {
 private static String watchedLog;

 @Rule
 public MethodRule watchman = new TestWatchman() {
  @Override
  public void failed(Throwable e, FrameworkMethod method) {
   System.out.println("[watch]fail");
   watchedLog += method.getName() + " " + e.getClass().getSimpleName()
     + "\n";
  }

  @Override
  public void succeeded(FrameworkMethod method) {
   System.out.println("[watch]success");
   watchedLog += method.getName() + " " + "success!\n";
  }
 };

 @Test
 public void test() {
  fail("Not yet implemented");
 }

 @Test
 public void test2() {

 }

}


ExternalResource
外部リソースなどのアクセスをテスト前後で行いたい場合に利用します。だいたいDBにアクセスしたり、ファイルアクセスだったりすると思います。クラスをインスタンス化したら、そのクラスのテスト前後にExternalResourceのbefore,afterが実行されます。


public class SampleClassTest {
 @Rule
 public ExternalResource resource = new ExternalResource() {
  Server myServer = new Server();
  @Override
  protected void after() {
   // 外部リソースの接続解除
   System.out.println("[ExternalResrouce after]");
   myServer.disconnect();
  }

  @Override
  protected void before() throws Throwable {
   // 外部リソース接続
   System.out.println("[ExternalResrouce before]");
   myServer.connect();
  }
 };
 @Test
 public void test() {
        }
}


テストメソッドの実行前後に起動されるメソッドの順序を調べてみました。

ExternalResource Before
Before
After
【テストメソッド実行】
ErrorCollector
Verifier
TestWatchman
ExternalResource After



同じ機能っぽいじゃないか?と思うクラスがあるとは思いますが、ユースケース別に
使い分けると非常によいクラスになると思うので、うまく使い分けていきましょう。
次はhamcrestあたりかな。

2011年9月22日木曜日

EMFのOCLの実装

今時OCL?ということもあるんですが、OCLを使うケースがあるので、調査した結果を
まとめます。
EMFのモデルに対してOCLをかける仕組みです。
org.eclipse.ocl.ecoreプラグインを依存関係につけます。

  1. OCLのインスタンス生成
  2. OCLHelperを作成
  3. contextの設定
  4. 評価するオブジェクトとOCLでevaluateを実行
  5. 戻り値はObject型だが、Booleanが戻ってくるので、OCLの評価がtrue,falseかの判定する。



以下ソースコード
import org.eclipse.ocl.ecore.OCL;
import org.eclipse.ocl.ecore.OCL.Helper;
import org.eclipse.ocl.ecore.EcoreEnvironmentFactory

        OCL ocl = OCL.newInstance(EcoreEnvironmentFactory.INSTANCE);
        OCLHelper helper = ocl.createOCLHelper();
        EClass context = targetObject.eClass();
        helper.setContext(context);
        EObject object = targetObject;
        String query;
        query = "self.parameter > 100";//

        try {
            Object result = ocl.evaluate(object, helper.createQuery(query));
            logger.error("", result.getClass(), result.toString());
        } catch (ParserException e) {
            logger.error("", e);
        }


eclipseのOCL説明

今回はOCLのinvariantの判定をするケースでもう一つの方法としては、
evaluateではなくcheckメソッドを使う方法もあるらしいです。

あとは、defを使ってquery operationを定義することもできる。OCLの記述と同じように記述し、evaludateを実行すれば、同じように取得ができる。


  • OCL資料

2011年9月19日月曜日

「関数プログラミングの集い」に参加

2011/09/17日にIIJにて開催されたので、行ってきました。
資料のリンクはこちら。参加人数はPARTAKEでは170人くらい参加だったそうです。
びっくり。

OCaml,Haskellerばかりのイベント?だと思ったので、Scalaユーザは少ないかな?
と思ったんですが、使っている言語ランキングは2位でした。意外と使われているんですねぇ。

あと、結構本を書いている人とか、名前を知っている人とかが来ていたし、
懇親会で話をしていると知識が豊富だなぁ〜と思って、まだまだだと実感。
最後にコップ本争奪じゃんけん大会があったんですが、さっくり負けてしまいました。
ちゃんとamazonでクリックします。

こういう勉強会に参加すると自分はまだまだだなと再認識されますね。
日々精進です。

以下各発表を簡単に


関数プログラミングの道しるべ

関数プログラミングについて簡単と。
関数型プログラミングの定義が統一はされていないため、言語によって異なる。
「世界で最も誤解されているプログラミング言語」→JavaScript。Scheme,Lispに近い。


モナドについて

モナドの説明について聞いてみたが、いまいちぱっとわからない。doのシンタックスシュガーがあるのはわかったけど。

ITプランニングにおける関数プログラミング

OCaml, GAE + Scala(Lift) ,haEx + OCaml + Coq, F#(Windowサーバのため),Androidアプリ(Scala)
枯れていない言語の採用って客の信頼を得ていないと無理だよねぇ。
影響がないところから、関数型で成功していけば、自ずと。


COBOL meets Haskell ~ Haskellを用いたCOBOLのリバースエンジニアリングツールの開発事例

昔のデファクト言語COBOLの設計書を作る。
strafunski、sglr,Haskellを使って、COBOLのバイナリを解析し、ロジックを解析し、
変数名、関数名などを日本語に変換していく。
日本じゃまだHaskellerはいないため、インド人を引っぱってくる。


言語アップデート1


  • scala
    • 2.9についてざーっと説明
    • 並列コレクション
    • I/O プロセス処理(scala.sys.process)
    • scala Dynamic ( method_misingみたいなもの)
    • Unfilterd, BlueEyes
    • Scalaz
  • Clojure
    • Clojure1.3リリース
    • ClosureScript(node.jsも対応)
    • Clojure on Heroku
      • git push
    • Clojure ハッカソン
      • Tokyo.clj
  • Erlang
    • サーバプログラミングフレームワーク
    • 軽量プロセス
    • 末尾再帰でホットアップデート
    • エラー処理はlet it die
    • emacsが今のところいいエディタ
    • rebar,Dialyzer,Typer,Tider,QuickCheck,Erjang,riak
  • Haskell
    • GHC7.2x
    • Hackage 、Yesod vs Snap,enumerator,attoparsec, blaze-builder , text
  • F#
    • 型プロバイダ、クエリ式、シーケンス
    • 既知の外部リソース(SQLServer)に適切に型をつけてくれる。
    • Null許容型演算子の追加。追加の仕方が結構泥臭い。
    • 自動実装プロパティ
  • SML#
    • grassを作った人
    • 目的はMLを普通の言語にすること。実用的な言語
    • OS,Cライブラリと直接i連携、すべてネイティブ
    • SQLの統合、分割コンパイル、
    • Cの関数はimportすれば使える。コールバックも使える。
    • 関係、演算、クエリも第一級
    • 分割コンパイル
      • smi,smlをもとにコンパイル。バイナリはCと同じため、Cとリンクができる。
  • OCaml
    • OCaml ver.3.12.0
    • First Class Module
      • TypeSafe Plugin
    • シグネチャーの合成
    • 一般化代数的データ型
    • OCSIGENのサイト。
      • webframework oscigen server, js_ocaml
LT


  • Coq
    • Coq
    • 定理証明支援言語
    • 証明駆動開発
  • F#
    • F#はREPLのスクリプトファイルがある。

  • Paraiso計画
    • 宇宙物理のシミュレーション計算にHaskellが利用
    • 未だにFortranの遺産が沢山。

2011年9月11日日曜日

「7つの言語7つの世界」を読了

まぁ、洋書で「seven languages in seven weeks」というタイトルの本です。
PDFで洋書なら読めるようなんですが、ちょっとPDFより本で読む方が好きなので、
和訳が出たので購入しました。

原文では7つの言語を7週間といっているが、1つの言語を三日間にわけて説明していますが、
7言語*3日=21日じゃね?とは思います。

Ruby、Io、Prolog、Scala、Erlang、Closure、Haskelの7つなんですが、やはり関数型の趣向が強いですよね。
Io,Prolog,Erlangはほとんど触ることのない言語について、学べたことは大きいし、ScalaやHaskellなどは
Erlangのアプローチを引き継いでいるので、その元となる言語を学べるのは大きい。
Prologの論理プログラミングの考え方もルールを与えて計算は言語に任せるというアプローチは非常に
面白いものだし、これはErlangも使っているし、他の言語でも使われていくのではないか?と思いました。


あと、この筆者はRuby好きで、静的型付けを嫌いなんだなぁということが見え見えなのがちょっと。。。。。
Scalaのの章の後Erlangの章では動的型付けについて、すばらしいだろうかと言わんばかりの説明だったのが
ちょっと嫌だなぁと思うところがありました。

あと、これは第一版だからしょうがないかもしれないが、誤字があったりもします。

  • 句読点が正しくない。(これはどうでもいい)
  • 説明がおかしい点がいくつか?(どこだったか忘れてしまった)
    • これについては、後日のせます。


でも、本当にいい本です。!!!っていうか、言語を知りたいという人は必読だとは思います。

2011年9月8日木曜日

Eclipse Virgo3.0がリリースだと

Eclipse Virgo3.0がリリースされたとInfoQで載っていたので、翻訳してみました。
お勉強もせねばという意味も持って。


Eclipse Virgo 3.0 Released



EclipseにSpring DM Serverプロジェクトの移行が完了した3.0のリリースをアナウンスしました。
リリースはWABデプロイメントに対してOSGiエンタープライズのテストのすべてをパスした最後の一部のパズルGemini Web Componentを含む。
Eclipse Virgoは、Tomcatに似た実行環境を提供する。
バンドルまたは、バンドル(PARs)のセットをインストールでき、アプリケーションサーバとして扱えるような実行環境。
Virgoはユーザインストールプログラムを使って、Virgoのランタイムの空間を分離するための領域の概念を使用する。

以前は、ネストするフレームワークを分離したが、最近は、パーティショニングを提供するフレームワークフックのEquinox実装を使ったBundle digraphをサポートのためアップデートした。

Equinoxの一部のため、EquinoxベースのOSGi実行環境でVirgoの外部で使用することができます。
他のOSGiフレームワークが新しいリゾルバフックをサポートしたとき、同様に他のOSGi実行環境に移植可能にすべきです。

このリリースの新しい点はWeb ComponentのためのJettyのサポートを含むバンドルです。
(Tomcat サポートも含まれている)
これは、Equinox RTスタック内の他のコンポーネントとの緊密な統合を提供します。

領域の分離の実装のため、実行環境はFelixからEquinoxに移行している。
しかしながら、これはデフォルトでFelixi Gogo shellを含むVirgoなので直接気づかされることはない。



サーバと同様Web app frameworkのsnapsがある。
snapsはweb applicationが重複するURLをいくつかのデータを共有して同一のWebサーバで共にホストになれる。
WABs(OSGi-ified WARS)がhostアプリケーションへサービスやURLを登録できる仕組みを提供する。
また、動的に利用可能なインストールされたコンポーネントを通して、ホストアプリがどのように反復できるかの方法も提供する。
Snapsは実行するためにEclipse Virgoを必要としている。
Eclipse VirgoをサポートするIDEプラグインのセットは開発中である。

WebベースOSGi開発や、多くのSpring概念を使ったりするのは、Eclipse VirgoをOSGiの世界へ簡単に遷移をさせることができる。
ユーザ、プログラマードキュメント同様利用可能チュートリアルがある。Virgo3.0はすぐにダウンロード可能である。



2011年9月2日金曜日

SBTを使い始める

とりあえず、sbtを使ってみるということで、インストールログを簡単に。

> curl -O http://simple-build-tool.googlecode.com/files/sbt-launch-0.7.7.jar
※
> wget http://simple-build-tool.googlecode.com/files/sbt-launch-0.7.7.jar
> ln -s sbt-launch-0.7.7.jar sbt-launch.jar
> vi  sbt
> java -Xmx512M -jar `dirname $0`/sbt-launch.jar "$@"
> chmod +x sbt
> ./sbt
kaz@earlgray:~/work/scala/sbt> ./sbt 
Project does not exist, create new project? (y/N/s) y
Name: SampleProject
Organization: ponta
Version [1.0]: 
Scala version [2.9.0]: 
sbt version [0.7.7]: 

ヘルプの内容

ヘルプ 内容
actions Shows all available actions
reload Reloads sbt, picking up modifications to sbt.version or scala.version and recompiling modified project definitions
current Shows the current project, Scala version, and logging level.
trace 'on', 'nosbt', 'off', or <integer> Configures stack trace logging. 'nosbt' prints stack traces up to the first sbt frame. An integer gives the number of frames to show per exception.
project <project name> Sets the currently active project. Use 'project /' to change to the root project or 'project ..' to change to the parent project.
projects Shows all available projects.
exit, quit Terminates the build.
set <property> <value> Sets the value of the property given as its argument.
get <property> Gets the value of the property given as its argument.
console-project Enters the Scala interpreter with the current project definition bound to the variable 'current' and all members imported.
builder Set the current project to be the project definition builder.


以下はプロジェクト作成時のログ


Getting net.java.dev.jna jna 3.2.3 ...
:: retrieving :: org.scala-tools.sbt#boot-app
confs: [default]
1 artifacts copied, 0 already retrieved (838kB/32ms)
Getting Scala 2.7.7 ...
:: retrieving :: org.scala-tools.sbt#boot-scala
confs: [default]
2 artifacts copied, 0 already retrieved (9911kB/54ms)
Getting org.scala-tools.sbt sbt_2.7.7 0.7.7 ...
downloading http://databinder.net/repo/org.scala-tools.sbt/sbt_2.7.7/0.7.7/jars/sbt_2.7.7.jar ...
[SUCCESSFUL ] org.scala-tools.sbt#sbt_2.7.7;0.7.7!sbt_2.7.7.jar (3128ms)
downloading http://databinder.net/repo/org.scala-tools.sbt/launcher-interface/0.7.7/jars/launcher-interface.jar ...
[SUCCESSFUL ] org.scala-tools.sbt#launcher-interface;0.7.7!launcher-interface.jar (336ms)
downloading http://databinder.net/repo/org.scala-tools.sbt/compile_2.7.7/0.7.7/jars/compile_2.7.7.jar ...
[SUCCESSFUL ] org.scala-tools.sbt#compile_2.7.7;0.7.7!compile_2.7.7.jar (342ms)
downloading http://databinder.net/repo/org.scala-tools.sbt/interface/0.7.7/jars/interface.jar ...
[SUCCESSFUL ] org.scala-tools.sbt#interface;0.7.7!interface.jar (341ms)
downloading http://databinder.net/repo/org.scala-tools.sbt/ivy_2.7.7/0.7.7/jars/ivy_2.7.7.jar ...
[SUCCESSFUL ] org.scala-tools.sbt#ivy_2.7.7;0.7.7!ivy_2.7.7.jar (515ms)
downloading http://databinder.net/repo/org.scala-tools.sbt/io_2.7.7/0.7.7/jars/io_2.7.7.jar ...
[SUCCESSFUL ] org.scala-tools.sbt#io_2.7.7;0.7.7!io_2.7.7.jar (352ms)
downloading http://databinder.net/repo/org.scala-tools.sbt/classpath_2.7.7/0.7.7/jars/classpath_2.7.7.jar ...
[SUCCESSFUL ] org.scala-tools.sbt#classpath_2.7.7;0.7.7!classpath_2.7.7.jar (333ms)
downloading http://databinder.net/repo/org.scala-tools.sbt/compiler-interface/0.7.7/jars/compiler-interface-bin.jar ...
[SUCCESSFUL ] org.scala-tools.sbt#compiler-interface;0.7.7!compiler-interface-bin.jar (344ms)
downloading http://databinder.net/repo/org.scala-tools.sbt/compiler-interface/0.7.7/jars/compiler-interface-src.jar ...
[SUCCESSFUL ] org.scala-tools.sbt#compiler-interface;0.7.7!compiler-interface-src.jar (335ms)
downloading http://databinder.net/repo/org.scala-tools.sbt/control_2.7.7/0.7.7/jars/control_2.7.7.jar ...
[SUCCESSFUL ] org.scala-tools.sbt#control_2.7.7;0.7.7!control_2.7.7.jar (336ms)
downloading http://databinder.net/repo/org.scala-tools.sbt/precompiled-2.8.1_2.8.1/0.7.7/jars/compiler-interface-bin.jar ...
[SUCCESSFUL ] org.scala-tools.sbt#precompiled-2.8.1_2.8.1;0.7.7!compiler-interface-bin.jar (344ms)
downloading http://databinder.net/repo/org.scala-tools.sbt/precompiled-2.9.0_2.9.0/0.7.7/jars/compiler-interface-bin.jar ...
[SUCCESSFUL ] org.scala-tools.sbt#precompiled-2.9.0_2.9.0;0.7.7!compiler-interface-bin.jar (346ms)
downloading http://databinder.net/repo/org.scala-tools.sbt/precompiled-2.8.0_2.8.0/0.7.7/jars/compiler-interface-bin.jar ...
[SUCCESSFUL ] org.scala-tools.sbt#precompiled-2.8.0_2.8.0;0.7.7!compiler-interface-bin.jar (345ms)
:: retrieving :: org.scala-tools.sbt#boot-app
confs: [default]
17 artifacts copied, 0 already retrieved (4379kB/58ms)
[success] Successfully initialized directory structure.
Getting Scala 2.9.0 ...
downloading http://repo1.maven.org/maven2/org/scala-lang/scala-compiler/2.9.0/scala-compiler-2.9.0.jar ...
[SUCCESSFUL ] org.scala-lang#scala-compiler;2.9.0!scala-compiler.jar (15211ms)
downloading http://repo1.maven.org/maven2/org/scala-lang/scala-library/2.9.0/scala-library-2.9.0.jar ...
[SUCCESSFUL ] org.scala-lang#scala-library;2.9.0!scala-library.jar (6277ms)
downloading http://repo1.maven.org/maven2/org/scala-lang/jline/2.9.0/jline-2.9.0.jar ...
[SUCCESSFUL ] org.scala-lang#jline;2.9.0!jline.jar (199ms)
downloading http://repo1.maven.org/maven2/org/fusesource/jansi/jansi/1.4/jansi-1.4.jar ...
[SUCCESSFUL ] org.fusesource.jansi#jansi;1.4!jansi.jar (244ms)
:: retrieving :: org.scala-tools.sbt#boot-scala
confs: [default]
4 artifacts copied, 0 already retrieved (20442kB/83ms)
[info] Building project SampleProject 1.0 against Scala 2.9.0
[info]    using sbt.DefaultProject with sbt 0.7.7 and Scala 2.7.7