マーチンファウラー著のリファクタリングの中でJavaのTestCaseを構築方法が載ってありましたが、
正直コードが理解しにくく、TestCaseを書いてもあまり利益があるのかと疑問でした。
でも、RubyのTestCaseはとてもわかりやすかったので、少しTestCaseについて書きます。
TestCaseの書き方
require "test/unit" require "テストしたい物" class テストしたい物のテストケース < Test::Unit::TestCase def setup @obj = テストしたい物の中のクラス.new end def test_メソッド名 assert_equal(メソッドの実行結果を比較する物, @obj.メソッド名()) end end
例えばObj.rbにこんなメソッドがあったとします。
## Obj.rb #リストを抽出する。 210 def list(value) 211 value.split(',') 212 end
このメソッドはどういうことをするのか知りたいときは
@obj = Obj.new
puts @obj.list("1,2,3")
↓
表示してくれて挙動が分かった。
ていうのは今まで...
ちゃんとtestCaseを書く。
#! /usr/bin/env ruby ## ObjTestCase.rb require "test/unit" require "Obj.rb" class ObjTestCase < Test::Unit::TestCase def setup @obj = Obj.new end def test_list assert_equal("", @obj.list("1,2,3")) end end
ここでテストしてみます。
% ObjTestCase.rb
Loaded suite /home/user/ruby/ObjTestCase
Started
.F.
Finished in 0.029616 seconds.
1) Failure:
test_list(ObjTestCase) [/home/user/ruby/ObjTestCase.rb:22]:
1 tests, 1 assertions, 1 failures, 0 errors, 0 skips
listメソッドは["1","2","3"]を返しているようです。
失敗しているのはassert_equalの結果で
["1","2","3"] が "" と違うと言ってくれている。
だから["1","2","3"]を入れてみる
def test_list assert_equal(["1","2","3"], @obj.list("1,2,3")) end
すると
% ObjTestCase.rb
Loaded suite /home/user/ruby/ObjTestCase
Started
...
Finished in 0.030652 seconds.
1 tests, 1 assertions, 0 failures, 0 errors, 0 skips
成功する。
こんな感じでTestCaseを増やしていく。
def test_coexist assert_equal([1, 2, 3..6, [1, 3, 5], [0, 2, 4], [3, 6, 9]], @Obj.coexist("1,2,3-6,1-5/2,0-5/2,3-9/3")) assert_equal([1, 3, 4], @Obj.coexist("1,3,4")) end def test_list assert_equal(["1", "2", "3", "45", "55"], @Obj.list("1,2,3,45,55")) assert_equal(["1","2","3"], @Obj.list("1,2,3")) end def test_range assert_equal([1,3,5], @Obj.range("1-5/2")) assert_equal([], @Obj.range("6-5/2")) end
assert_equalばかりですが、
他のメソッドもあります。http://doc.okkez.net/191/view/library/test.unit
http://doc.okkez.net/191/view/class/Test=Unit=Assertions
書くのはめんどくさいかもしれないですが、書いてる内にプログラムの内容が
頭に整理されていくような気がします。それとわざと失敗を誘うと
メソッドの挙動が分かるのでそれを利用すればよいかもしれません。
動機
・cronはsuspend状態から実行できない。
・目覚まし機能をつけたい。
・Rubyでいろいろしたい。
など...
準備
初めにやっておくこと
・復帰からのパスワード入力をなしにする。
suspendのチェックをはずす。
PC復帰について
参考にさせってもらったサイト
PCを指定時刻に起動する
http://lostman-worlds-end.blogspot.com/2008/12/pc.html
PCのアラーム設定。
http://www.mythtv.org/wiki/ACPI_Wakeup#Using_.2Fsys.2Fclass.2Frtc.2Frtc0.2Fwakealarm
上記のサイトのおかげでsuspend状態からでも(多分shutdownからでも)
PCが復帰できました。
簡単に説明すると
$SECSに1970-01-01 00:00:00 UTC からの秒数を設定
これでだけでPCが復帰します。
しかし、パーミッション云々などの問題で私はハマりました。
そのため、スクリプトを作っておくといいです。
#!/bin/sh
then
echo usage:
fi
SECS=`date -u --date "$1 $2" +%s`
echo 0 > /sys/class/rtc/rtc0/wakealarm
echo $SECS > /sys/class/rtc/rtc0/wakealarm
cat /proc/driver/rtc
alarm.shの使い方
% sudo ./alarm.sh 2009-06-26 12:45:00 ##時刻を直接設定
##現在の時刻の5分後に設定
rtc_time : 22:05:01
alrm_time : 22:10:00 ## ここが表示されれば成功
alarm_IRQ : yes
alrm_pending : no
24hr : yes
periodic_IRQ : no
update_IRQ : no
HPET_emulated : yes
DST_enable : no
periodic_freq : 1024
batt_status : okay
あとはPCが復帰するかsuspendしてテストしてみてください。
cronと連携
cronを実行するにはPCが動いていなければならないので、
Rubyを使って実行五分前に復帰できるようなプログラムを
作りたいと思っていました。
http://bitbucket.org/shiro/cronwakeuprb/src/tip/cronWakeup.rb
あとはこれを実行するタイミングですが、
やはりsuspendをする前が絶妙です。
参考サイト http://www.revulo.com/blog/20090512.html
Ubuntu8.10では
にスクリプトを置いておくとsuspendやshutdown前にプログラムが実行されるようです。
ソースを入手と解凍
% wget -O cronWakeup.gz http://bitbucket.org/shiro/cronwakeuprb/get/tip.gz
ファイル実行権限を変更
% cd cronwakeuprb/
実行するスクリプトを置く
#!/bin/sh
/home/user/cronwakeuprb/cronWakeup.rb init
root権限で実行するように設定
cronWakeup.rbのについて
使い方
% sudo cronWakeup.rb init #アラームを設定
特定のプログラムしか復帰したくないという場合は
rootユーザーで分けると便利かもしれません。
% sudo crontab -e #rootのcrontabを設定
設定...
問題
時間設定が完璧でない。
でcronを設定できます。
は設定できますが、
範囲設定やリスト設定は使えません。
上記設定使えません。
今後
上記の問題を解決できたらいいなと思っています。
あとはリファクタリングしていきたいです。
何かご指摘あれば、よろしくお願いします。
その他
cronを駆使してamarokをコントロールするという
似たようなプログラムを発見しました。
とすると
include Comparable
文字列のクラスです。
NUL 文字を含む任意のバイト列を扱うことができます。
文字列の長さにはメモリ容量以外の制限はありません。.......
とこんなかんじで出てくる。
とすると
String#% String#* String#+ String#<< String#<=> String#== String#=~
String# String#= String#ascii_only? String#bytes String#bytesize
String#capitalize String#capitalize! String#casecmp String#center
String#chars String#chomp String#chomp! String#chop String#chop!
String#chr String#clear String#codepoints String#count String#crypt
......
とこんなかんじ。
う〜見にくいな。
ということで見やすく
% refe String# | grep -o -e "String#[a-zA-Z0-9_?\!%*+<>=~]*\W*"
String#+
String#ascii_only?
...
見やすくなったでも長い・・・
横にメソッドの説明するようにできないでしょうか?
String#% printf と同じ規則に従って args をフォーマットします。
String#* 文字列の内容を times 回だけ繰り返した新しい文字列を作成して返します。
String#+ 文字列と other を連結した新しい文字列を返します。
...
とこんな感じで
正規表現でパパッと。
% refe String | grep "。" | grep -n -e "。" | grep "^1:"
1:文字列のクラスです。
説明文抽出するだけでできませんでした。orz...また今度
mas-higaさん情報ありがとうございます。
ということでrubyでソース書いてみました。
#! /usr/bin/env ruby # vi: set fileencoding=utf-8 : ## referb.rb if $* == [] refeString = `refe -l` refeString.each_line() {|line| print line + %x{refe "#{line.chomp}" | grep '。' | grep -n -e '。' | grep '^1:' | grep '。' | grep -o -e '[^1].*[。]$ '} + "\n" } elsif $*[0][$*[0].length-1] == "#" refeString = `refe -l #{$*[0]}` refeString.each_line() {|line| print line + %x{refe "#{line.chomp}" | grep '。' | grep -n -e '。' | grep '^1:' | grep '。' | grep -o -e '[^1].*[。]$ '} + "\n" } else refeString = `refe #{$*[0]}` puts refeString end
んで
とすると
:printf と同じ規則に従って args をフォーマットします。
:文字列の内容を times 回だけ繰り返した新しい文字列を作成して返します。
String#+
:文字列と other を連結した新しい文字列を返します。
....
になる
でも遅いしちゃんと抽出できてないので使えないなこれは...
bitclust解析したらできるかな?
説明は出ませんが。