Java8 がリリースされてから半年ほど経過しました。
そろそろ Lambda 式を利用したライブラリやらフレームワークやらが出てないかなと GitHub で java lambda
で検索したところ、いくつか目についたものがあったので試してみた。
#Lambda Behave
##説明
テスティングフレームワーク。
Jasmine みたいな感じで、自然言語に近い形でテストケースを記述できる。
流れるようなインターフェースでテストが書けるのもいいけど、テストケース(spec)を文字列で定義できるのが何気に嬉しい。
##Hello World
###インストール
testCompile 'com.insightfullogic:lambda-behave:0.3'
###実装
package sample.lambda_behave;
import static com.insightfullogic.lambdabehave.Suite.*;
import java.util.Stack;
import org.junit.runner.RunWith;
import com.insightfullogic.lambdabehave.JunitSuiteRunner;
@RunWith(JunitSuiteRunner.class)
public class StackSpec {{
Stack<String> stack = new Stack<>();
describe("a stack", it -> {
it.isSetupWith(() -> {
System.out.println("isSetupWith");
stack.clear();
});
it.should("be empty when created", expect -> {
expect.that(stack).isEmpty();
});
it.isConcludedWith(() -> {
System.out.println("isConcludedWith");
stack.clear();
});
});
}}
isSetupWith
21:22:13.268 [main] INFO c.i.l.i.reports.SpecificationReport - be empty when created has succeeded
isConcludedWith
###説明
####JUnit で動かせる
-
com.insightfullogic.lambdabehave.JunitSuiteRunner
を@RunWith
に指定することで、 JUnit で動かせる。
####インスタンス初期化ブロックにテストを書く
- テストコードを「インスタンス初期化ブロック」に記述しているけど、 must ではない。
- コンストラクタにテストコードを書いても動く。
- たぶん、コンストラクタの中に書くよりエレガントだから、インスタンス初期化ブロックに書いているのだと思う。
####suite を記述する
-
Suite.describe()
を使って suite を記述する。
####spec を記述する
-
describe()
メソッドの第二引数に Lambda 式を渡す。 - Lambda 式には
Description
のインスタンスが渡される。 -
Description
のshould()
メソッドを使って spec を記述する。
####メインのテストコードを記述する
-
should()
メソッドに渡した Lambda 式には、Expect
のインスタンスが渡される。 -
Expect
のthat()
メソッドを起点にして、流れるようなインターフェースで expectation が書ける。 -
com.insightfullogic.lambdabehave.expectations
パッケージの下に expectation を書くためのクラスがあり、メソッドを眺めてみるだけでも何となくどんなチェックができるかが分かる。 -
is()
メソッドは Hamcrest の Matcher を受け取るので、組み込みのメソッドじゃ足りないという場合は Matcher を自作したり、他のライブラリの Matchar を流用したりできる。
##依存関係
com.insightfullogic:lambda-behave:0.3
+--- junit:junit:4.11
| \--- org.hamcrest:hamcrest-core:1.3
+--- org.hamcrest:hamcrest-all:1.3
+--- org.mockito:mockito-all:1.9.5
+--- org.slf4j:slf4j-api:1.5.6 -> 1.7.6
\--- ch.qos.logback:logback-classic:1.1.2
+--- ch.qos.logback:logback-core:1.1.2
\--- org.slf4j:slf4j-api:1.7.6
#micra
##説明
Ruby の Sinatra にインスパイヤされて製作された Web フレームワーク。
ちょっとした Web アプリを作りたいときに便利かも。
ちなみに Sinatra は使ったことないです。
##Hello World
###インストール
Maven には公開されていないので、 zip で落とすか git clone してから gradlew jar
する。
build/libs
の下に jar が出力されるので、クラスパスに追加する。
###フォルダ構成
micra
|-lib/
| `-micra-master.jar
|-src/main/
| |-java/sample/micra/
| | `-SampleMicraServlet.java
| `-webapp/WEB-INF/
| `-web.xml
`-build.gradle
###build.gradle
apply plugin: 'jetty'
repositories {
mavenCentral()
}
dependencies {
providedCompile 'javax.servlet:javax.servlet-api:3.1.0'
compile 'com.github.spullara.mustache.java:compiler:0.8.14'
compile fileTree(dir: 'lib', include: '*.jar')
}
mustache
は micra が利用している。
###実装
package sample.micra;
import com.noelherrick.MicraServlet;
public class SampleMicraServlet extends MicraServlet {{
get("/", (req, res) -> "Hello Micra!!");
}}
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
version="3.0">
<servlet>
<servlet-name>SampleMicraServlet</servlet-name>
<servlet-class>sample.micra.SampleMicraServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>SampleMicraServlet</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
</web-app>
###実行
> gradle jettyRun
:compileJava UP-TO-DATE
:processResources UP-TO-DATE
:classes UP-TO-DATE
> Building 75% > :jettyRun > Running at http://localhost:8080/micra
ブラウザを開いて http://localhost:8080/micra/
にアクセスする。
###説明
説明不要なくらい見たまんまな感じで実装できる。
HTTP メソッドに対応するリクエストハンドリング用のメソッドは get
, post
, put
, delete
が用意されている。
##パラメータの取得
###クエリパラメータ
package sample.micra;
import com.noelherrick.MicraServlet;
public class MicraSampleServlet extends MicraServlet {{
get("/", (req, res) -> "parameter = " + req.getParameter("p"));
}}
###ルートパラメータ
package sample.micra;
import com.noelherrick.MicraServlet;
public class MicraSampleServlet extends MicraServlet {{
get("/{name}", (req, res) -> "parameter = " + req.getRouteParameter("name"));
}}
##ルーティングの条件設定
package sample.micra;
import com.noelherrick.MicraServlet;
public class MicraSampleServlet extends MicraServlet {{
get(
"/",
req -> req.isParameter("name"),
(req, res) -> "name = " + req.getParameter("name")
);
get(
"/",
req -> req.isParameter("id"),
(req, res) -> "id = " + req.getParameter("id")
);
}}
- 第2引数で渡した Lambda 式が true を返す時のみ、そのルーティングが適用される。
#Lambda Builder
##説明
Groovy の Builder みたいな感じで XML を構築できるライブラリ。
テストがないのがキツイ(バグっぽい動きもする)。
けど、今までの Java じゃできなかった実装スタイルに Lambda の可能性を感じた。
(Groovy 使ったほうが手っ取り早い?)
##Hello World
###インストール
これも Maven リポジトリにはないっぽいので、コードを落としてきて mvn package
でビルドする。
target/
の直下に jar が出力されるので、クラスパスに追加する。
###build.gradle
apply plugin: 'application'
repositories {
mavenCental()
}
dependencies {
compile fileTree(dir: 'lib', include: '*.lib')
}
lib/
の下に生成した jar ファイルを置いておく。
pom.xml
には commons-beanutils
が依存関係に入っているけど、実装見る限り使ってないので要らないと思う。
###実装
package sample.lambdabuilder;
import java.util.Arrays;
import java.util.List;
import com.github.lambdabuilder.MarkupBuilder;
import com.github.lambdabuilder.XmlMarkupBuilder;
public class Main {
public static void main(String[] args) {
List<String> list = Arrays.asList("hoge", "fuga", "piyo");
MarkupBuilder html = new XmlMarkupBuilder(false, "html");
html.el("head", () -> {
html.el("title", "Lambda Builder");
})
.el("body", () -> {
html.el("h1", "Hello Lambda Builder!!")
.el("ul", () -> {
list.forEach(s -> {
html.el("li", s);
});
});
});
System.out.println(html.get());
}
}
###実行結果
<html>
<head>
<title>Lambda Builder</title>
</head>
<body>
<h1>Hello Lambda Builder!!</h1>
<ul>
<li>hoge</li>
<li>fuga</li>
<li>piyo</li>
</ul>
</body>
</html>
#underscore
##説明
謎の激戦区。
これが最近もコミットされてて、かつテストも書かれている。
ということで、これを使ってみる。
##Hello World
###インストール
リポジトリのトップに jar が置いてあるので、それをダウンロードしてきてクラスパスに追加する。
###実装
package sample.underscore;
import java.util.Arrays;
import java.util.List;
import com.github.underscore._;
public class Main {
public static void main(String[] args) {
List<String> list = Arrays.asList("hoge", "fuga", "piyo");
_.each(list, System.out::println);
}
}
###実行結果
hoge
fuga
piyo
Underscore.js と違って、インデックスとかは渡してくれない。
Stream API があれば必要ないか。