Hatena::ブログ(Diary)

みずぴー日記

2010-07-09(金)

omake + oUnitでTDD!

| omake + oUnitでTDD! - みずぴー日記 を含むブックマーク

明日は、TDD Bootcamp名古屋です。

というわけで、自分のoUnit + omakeでTDDな環境を晒してみます。もっとクールな方法があったら教えてください><。

ちなみに、構築したサンプルはno titleに置いてあります。

ディレクトリ構造

ディレクトリ構造はこんな感じで、本番コード(./src)とテストコード(./test)が別ディレクトリに分かれています。

.
|-- OMakefile
|-- OMakeroot
|-- src
|   |-- OMakefile
|   |-- fact.ml
|   `-- main.ml
`-- test
    |-- OMakefile
    `-- fact_test.ml

ルートのOMakefile

ルートのOMakefileではサブディレクトリを認識させます。ついでにocamlfindも有効にしておきます。

.PHONY: all clean check

USE_OCAMLFIND = true
OCAML_FLAGS=-w A -warn-error A

if $(not $(OCAMLFIND_EXISTS))
   eprintln(This project requires ocamlfind, but is was not found.)
   eprintln(You need to install ocamlfind and run "omake --configure".)
   exit 1

NATIVE_ENABLED = $(OCAMLOPT_EXISTS)
BYTE_ENABLED = $(not $(OCAMLOPT_EXISTS))

.SUBDIRS: src test

clean:
	rm -f *~ *.opt *.cmi *.cmx *.o *.omc

本番コード側

適当なモジュールを書きます。とりあえず階乗で。

(* src/fact.ml *)
let rec fact n =
  if n = 0 then
    2 (* BUGGGGYYYY *)
  else
    n * (fact (n - 1))

そしてOMakefile。

普通のOCamlプログラムとしてビルドするだけでなく、ライブラリとしてもビルドします。

# src/OMakefile
.PHONY: all clean

FILES[] =
	fact
	main

LIB = target
PROGRAM = main

.DEFAULT: $(OCamlProgram $(PROGRAM), $(FILES))

OCamlLibrary($(LIB), $(FILES))

clean:
	rm -f *~ *.opt *.cmi *.cmx *.o *.omc *.cma *.cmxa $(PROGRAM) *.a

テストコード側

oUnitを使ったテストコードを書きます。

(* test/fact_test.ml *)
open OUnit
open Fact

let _ = run_test_tt_main begin "fact.ml" >::: [
  "fact(3)" >:: begin fun () ->
    assert_equal 6 (fact 3)
  end
] end

そしてテストプログラムビルドします。

このとき先ほど作ったライブラリを使うようにします。

# test/OMakefile
.PHONY: all clean check
OCAMLINCLUDES += ../src

FILES[] =
	fact_test

OCAMLPACKS[] =
	oUnit

PROGRAM = test
OCAML_LIBS += ../src/target

clean:
	rm -f *~ *.opt *.cmi *.cmx *.o *.omc *.cma *.cmxa

.DEFAULT: all

all : $(OCamlProgram $(PROGRAM), $(FILES))

check : all
	./$(PROGRAM)

実行例

$ omake check
*** omake: reading OMakefiles
*** omake: finished reading OMakefiles (0.23 sec)
- build test <check>
+ ./test
F
======================================================================
Failure: 1:0:fact

OUnit: not equal
----------------------------------------------------------------------
Ran: 1 tests in: 0.00 seconds.
FAILED: Cases: 1 Tried: 1 Errors: 0 Failures: 1 Skip:0 Todo:0
*** omake: 38/40 targets are up to date
*** omake: failed (4.16 sec, 0/3 scans, 7/14 rules, 13/130 digests)
*** omake: targets were not rebuilt because of errors:
   <phony <test/check>>

2009-04-15(水)

omakeでletterサイズじゃないPDFを生成する

| omakeでletterサイズじゃないPDFを生成する - みずぴー日記 を含むブックマーク

omakeでLaTeXをコンパイルすると身長が伸びるらいいけど、PDFのサイズがletterになってしまう。

これを変えたい場合は、DVIPDFMFLAGSを変えてやればいい。

# A4で生成したい
DVIPDFMFLAGS = -p a4

LaTeXDocument(document, document)
.DEFAULT: document.pdf document.dvi

RoccoRocco 2009/04/15 21:51 自分でポストしておきながら、個人的には less ではなく、lv への alias だったりします。

2008-09-28(日)

omake with camlp4

| omake with camlp4 - みずぴー日記 を含むブックマーク

pa_ooを使ったソースコードをomakeでビルドしたかったので、いろいろ試してみた。もっと賢い方法がある気がするけど、とりあえず動くよ。

ディレクトリ構造

+-camlp4-omake/
  |
  +-camlp4/
  | |
  | +-OMakefile
  | |
  | +-pa_oo.ml
  |
  +-main.ml
  |
  +-OMakefile
  |
  +-OMakeroot

main.ml

サンプルコードはこんな感じ。

let o = 
  {| x = "hello"; y = "world" |}

let _ =
  print_endline o#x

camlp4/OMakefile

camlp4/以下は普通にビルドする。

BYTE_ENABLED = true

# camlp4
OCAMLINCLUDES += -I +camlp4
OCAMLPPFLAGS  += -pp camlp4orf
OCAMLDEPFLAGS += $(OCAMLPPFLAGS)

OCamlProgram(pa_oo,pa_oo)

OMakefile

依存関係を解決する前に、pa_oo.cmoをビルドするようにしてやる。

# サブディレクトリ設定
.SUBDIRS: camlp4

# 追加ルール。依存関係を解決する前にpa_ooをビルドする
.SCANNER: scan-ocaml-%.ml: %.ml camlp4/pa_oo.cmo
	section 
		$(OCamlScanner $<)

# フラグ設定
BYTE_ENABLED = true
OCAMLPPFLAGS  += -pp 'camlp4o camlp4/pa_oo.cmo'
OCAMLDEPFLAGS += $(OCAMLPPFLAGS)

# あとは通常通り
FILES[] =
    main
.DEFAULT: $(OCamlProgram main, main)

2008-09-24(水)

複数ディレクトリにまたがるomake

| 複数ディレクトリにまたがるomake - みずぴー日記 を含むブックマーク

こんな風にソースコードが複数ディレクトリに分かれている場合のomakeの書き方。

+-project_name/
  |
  +-main.ml
  |
  +-OMakefile
  |
  +-OMakeroot
  |
  +-test/
    |
    +-OMakefile
    |
    +-OMakeroot
    |
    +-test_main.ml

OMakefileの書き方

まず各ディレクトリにOMakefileを用意する。

project_name/OMakefileではサブディレクトリを指定する。それ以外の部分は通常通り。

.SUBDIRS: test

ビルド

すると、project_name/で

# cd test; omake suiteと等価
$ omake test/suite

# PHONYターゲットの場合は、test/がいらない
$ omake test-run

といった感じでビルドできる。

参考: Rules

ところで

OCamlってファイル名がモジュール名になるから、ディレクトリが違っても同名のファイルって許されないんだよね。

だからディレクトリを分けても、Mainモジュールが2つ持てたりはしないよ。

追記:

これは、ocamlc -packで解決できるそうです。詳しい解説もいただきました。ありがたいことです。

camlspottercamlspotter 2008/09/24 10:22 OMakeroot が必要なのはトップディレクトリだけのはずですよ。

ocamlc -pack を使えば、同じ名前の .ml があっても大丈夫です。

mzpmzp 2008/09/24 11:24 おおお、-packすばらしいです。もうファイル名が被る心配をしなくていいんですね。

GemmaGemma 2008/09/25 01:14 ocamlはパッチがいるかも。
https://issues.apache.org/jira/browse/THRIFT-125
いらんもんを省くと楽になるかも。
./configure --disable-gen-java --disable-gen-py --disable-gen-cocoa --disable-gen-ocaml --disable-gen-csharp --without-java --without-erlang --without-csharp