Keep on moving

あんまりまとまってないことを書きますよ

PySpaについてつらつらと( #PySpa アドベントカレンダー 15日目)

この記事はPySpaアドベントカレンダーの15日目の記事です。
PySpa系のイベントには思い入れが強いせいか、考えがうまくまとまらなかったのでダラダラした感じで書いていきます。


f:id:Ehren:20121215232601j:plain
来宮神社のにゃんこ

Python温泉とは

Vの人が書いている説明が↓にあります。

https://github.com/pyspa/pyspa

基本的に温泉のついでに、各自やりたいことを持ち寄って過ごす感じです。
ゲームやったり、だべったり、おいしい昼ご飯を食べにいったり、海を見に行って、ついでにコードを書く感じ。
かなり自由度は高いです。この自由度が非常に気持ちいいイベントです。
毎回、どこかで面白い事がおこっています。
よく読ませていただくブログの中の人がよく参加されてるので、たまにふわふわした気分になったりします。

私の参加履歴

私のPySpa系のイベントへの初参加は2009年頃にあったPython旅館(後にCodeCamp)というイベントでした。
当時PythonでAtndのイベント情報を取ってくるやつとかが作りたくて参加した覚えがあります。
@ さんとかがラジコンヘリを飛ばしてたり、 @ さんが
言語を作ってたりしてるのをみてて、
「なんかすごいところに飛び込んじゃったなー」と言う感想でした。
@ さんにNTEmacsを教えてもらったりしました。
その後、PySpa本体に参加させていただくようになりました。

初参加はPySpa 第7回

@ さんとか @ さんとJSの話をしていた気がする。
確かこのときまだv0.1だったnode.jsを触っていたような...
こんなに流行って 東京Node学園祭2012みたいな大きなイベントが日本で開かれるようになるとはねー

第9回のときはまじめにブログを書いた...らしい

http://masahito.hatenablog.com/search?q=pyspa

このとき裏でJavaScriptテクニックバイブル ~効率的な開発に役立つ150の技:書籍案内|技術評論社のネタだしのために、@ さんと一緒に @ さんを拉致って話し合いをしたはず。
後確か、ここでRiakの話をどなたかに聴いて分散KVSとか超面白そうとか思った覚えが。。。
仕事でP2Pを扱うこととかやってみたいと思って今の会社に入る動機になったので、PySpaのお陰で今の会社にいると行っても言い過ぎではないかも。

第10回

今の会社に転職後に参加。確かJS本の原稿書いたり、JVM上で動くWebFramework Play!flameworkの翻訳を手伝ったりしてました。
Play!flameworkはお仕事でも使ってるのでいろいろ勉強になった覚えが。

Python 温泉 2012.10

主に温泉に入ってました。あとScalaのテスト周りを調べてたはず。
@tk0miya さんのblockdiagの新機能が面白かったり、噂のタバコスペースにちょろっと混ぜてもらったりしてました。
夜がPySpaの醍醐味ってのは本当なんだなってのを実感しました。

まとめ

PySpaは参加する前は非常に敷居が高いと思ってたんですが、参加してみると全然そういう事もなくて非常に楽しいです。
主に技術力が高い方とか仕事をしながら本を書いている方たちが多いので、そういう方達がどう言う考え方で
作業をしてるのかを聴けたりするので、自分のやり方を見直したりできます。
もちろん聴くばかりじゃなくて、自分のしってることを説明したりできるのも面白いところです。
なんていうか、みんなそれぞれ何かの専門家なので、そこで新しいものができていくところをみれるのもこのイベントの
醍醐味なんじゃないでしょうか。

個人的には、 主催の @ さん、 @ さんの連携にいつも感心させられています。いいチームだなぁ。いつも主催お疲れ様です。
PySpaは不定期になりましたけど、今後も続くなら是非参加させていただきたいです。

明日は

明日は @ さんがPySpaへの思いを語ってくれます。
明日もお楽しみに!!

Scala(っていうかCommonsEmail)でMail送信をテストしたい

ScalaでEmail送りたいと思ってググったらCommons Email - Homeってのを
使うのがいいみたい。内部的にはJavaMailAPIってのを使ってるみたいですね。

Apache Commons Emailでメールを送信する

exception周りとか書いてないけどこんな感じで送信できます。

import org.apache.commons.mail.SimpleEmail

case class SendMailInfo(to: String, from: String, subject: String, msg: String)

class MyMailSender(sendHostName: String, charSet: String = "UTF-8") {

 def sendMail(mailInfo: SendMailInfo) {

   new SimpleEmail {
     setCharset(charSet)
     setHostName(sendHostName)
     setFrom(mailInfo.from)
     addTo(mailInfo.to)
     setSubject(mailInfo.subject)
     setMsg(mailInfo.msg)
   }.send
 }
}

テストの書き方

ユニットテストするときにはhttp://java.net/projects/mock-javamailを使うとモックを使ったテストが書けるみたい。*1
Commons EmailはJavaMail APIを使ってるのでこのライブラリ使えばmockを使ったテストが可能です。
今回は送信をチェックしたいのでこれでテストします。

import org.scalatest.FunSuite
import org.scalatest.BeforeAndAfter
import org.jvnet.mock_javamail.Mailbox

class MyMailSenderTest extends FunSuite with BeforeAndAfter {

  val HOST_NAME = "mail.example.com"
  var mailSender: MyMailSender = null

  before {
    mailSender = new MyMailSender(HOST_NAME)
    //clear Mock JavaMail box
    Mailbox.clearAll()
  }

  test("testSendInMockWay") {

    val subject = "Test2"
    val body = "Test Message2"
    mailSender.sendMail(SendMailInfo("to@example.com", "from@example.com", subject, body))

    // check JavaMail box
    val inbox = Mailbox.get("to@example.com")
    assert(inbox.isEmpty === false)
    assert(inbox.size() === 1)
    assert(subject === inbox.get(0).getSubject)
    assert(body === inbox.get(0).getContent)

 }
}

対象バージョン

  • Apache Commons Mail 1.2
  • mock-javamail 1.9

sbt

      libraryDependencies ++= Seq(
	"org.apache.commons" % "commons-email" % "1.2",

        // test
        "org.scalatest" %% "scalatest" % "1.8" % "test",
	"org.jvnet.mock-javamail" % "mock-javamail" % "1.9" % "test",

      )

*1:このライブラリJenkins作者のkohsukeさんが書いてるんですなぁ

Scalatra-scalatestでServletのテスト

ちなみにScalatra-ScalaTestを使って http://masahito.hatenablog.com/entries/2012/11/14 風のテストは以下のように書きます

package com.github.masahitojp.app

import org.scalatra.test.scalatest.ScalatraFunSuite


class MyScalatraServletSpec extends ScalatraFunSuite {
  // `MyScalatraServlet` is your app which extends ScalatraServlet
  addServlet(classOf[MyScalatraServlet], "/*")

  test("simple get") {
    get("/") {
      status should equal (200)
      body should include ("world!")
    }
  }
}

参考

servletのテスト

ServletなものへのテストはServletTesterを使って以下のように書くらしい。
ちなみにJUnit 4.10 + Jetty 7.Xでの書き方です。

http://docs.codehaus.org/display/JETTY/ServletTester

import org.junit.Before;
import org.eclipse.jetty.testing.HttpTester;
import org.eclipse.jetty.testing.ServletTester;
import org.junit.Test;

import static junit.framework.Assert.assertEquals;
import static org.junit.Assert.assertTrue;

public class WebAppTest {
	private ServletTester tester;
	private HttpTester request;
	private HttpTester response;

	@Before
	public void setUp() throws Exception {
		this.tester = new ServletTester();
		this.tester.setContextPath("/");

		this.tester.addServlet(ApiWebAppServlet.class, "/api/*");
		this.tester.start();

		this.request = new HttpTester();
		this.response = new HttpTester();
		this.request.setMethod("GET");
		this.request.setHeader("Host", "tester");
		this.request.setVersion("HTTP/1.1");
	}
	@Test
	public void testHomepage() throws Exception {
		this.request.setURI("/api/node/");
		this.response.parse(tester.getResponses(request.generate()));
		assertTrue(this.response.getMethod() == null);
		assertEquals(200, this.response.getStatus());
		assertEquals("Hello World", this.response.getContent());
	}
}

はてなブログへ移転

アウトプットの集大成として本が出せたので、気分転換にはてなブログへ移行しました。
markdownとかはてな記法に対応してくれてるので、私の使い方としては問題ないかなー*1

*1: でもrestructredTextでも書きたいなー

Scalatra+scalatra-lift-jsonでJSON

ScalatraでJSONをrequest/responseで扱いたい場合にはscalatra-jsonを使うのが便利。

導入方法

build.sbtに以下のように追加します。
※バージョンは適宜変えてください。

libraryDependencies ++= Seq(
"org.scalatra" % "scalatra" % "2.1.1",
"org.scalatra" % "scalatra-lift-json" % "2.1.1"
)

使用例

↓のエントリを真似して書いてみた例

http://d.hatena.ne.jp/tototoshi/20120526/1338032893

感想

RESTful APIでpost/put/deleteなどでJSONを受ける際に、parsedBodyにpattern matchがすぐに使えるので
ソースコードの見通しが良くなるのが非常に嬉しいですね。