2006-11-07
伺かIO
- おもむろに require 'ukagaka_io'
- 適当に UkagakaIO を open する
- STDOUT/STDERR と差し替える
require 'ukagaka_io'
UIO = UkagakaIO.open('192.168.155.200', 9801)
STDOUT.reopen UIO
STDERR.reopen UIO
ほぼ全部の出力が伺かに…!
最初、test の結果の UI でなんか console 以外に表示させたくて伺かの接続用インタフェつくって、って思ったけどそもそも Socket 自体 IO の子クラスだし、つーことで UkagakaIO を作ってみた。write ラップして 1書き込みごとに伺かに出力だと、間隔が短すぎてわけわかんなくなったのでんげぇ適当にタイマーとバッファ処理。
require 'socket'
require 'nkf'
require 'thread'
class UkagakaIO < TCPSocket
def to_utf8(str)
NKF::nkf('-m0 -w', str)
end
HEADERS = {
'Sender' => 'Ruby UkagakaIO',
'Script' => '',
'Charset' => 'UTF-8',
}
BREAK = "\r\n"
def write(msg, force = false)
@msg_buffer ||= ''
@msg_buffer << to_utf8(msg).gsub(/\r?\n/, '\n')
if force
headers = HEADERS.clone.update('Script' => @msg_buffer)
h = ['SEND SSTP/1.4']
h << headers.map{|k,v| "#{k}: #{v}"}
message = h.join(BREAK).concat(BREAK * 2)
result = super(message)
@msg_buffer = ''
reconnect!
result
else
timer
end
end
def timer
@mutex ||= Mutex.new
@mutex.synchronize {
return if @timer_stated
@timer_stated = true
}
begin
Thread.new {
sleep @sec || 0.1
write('', true)
}
ensure
@timer_stated = false
end
end
def reconnect!
reopen(self.class.open(*@args))
end
def self.open(*args)
@at_exit_set ||= at_exit { Thread.list.each {|t| t.join(0.1) rescue nil} }
io = super
io.instance_variable_set(:@args, args)
io
end
end
r14
Test::Base#spec_type を廃止して Test::Base::Spec オブジェクトが渡ってくるように。spec.foo でも spec[:foo] でもデータを取得できるようになった。あとリファクタリング。
instance のとある変数名から特異メソッド作る方法って、
instance.instance_eval "def #{method_name};end"
ってやる方法しか無いんだっけ?もっとベターな方法あったら誰かおしえて><
特定インスタンスの binding 取得し隊
あー。instance.instance_eval { binding } じゃなくて instance.__send__(:binding) でもいいのね
LDR で特定レートをすべて既読にする bookmarklet
未読たまりまくるとそのレートを読む気がなくなるのでそれをリセットするのに! sub.rate == 1 の値を 0~5 で適当に変更。LDR の開発者様におしえてもらった><
javascript:(function(){var o=Ordered.list;Ordered.list=subs.model.list.filter(function(sub){return sub.rate == 1}).pluck("subscribe_id");Control.mark_all_read();Ordered.list=o;})();
r13
Test::Base.spec_type で spec のタイプを hash or struct で選べるように。デフォルトだと struct。ていうか spec という名前で良いのだろうか、という最大の疑問。
require 'test/base'
class SpecTypeHashTest < Test::Base
default_filters %w(.strip)
spec_type :hash
def run_tests(spec)
assert_equal spec[:foo], 'example'
assert_equal spec[:bar], 'example'
assert_equal spec[:baz], 'example'
end
end
__END__
===
--- foo: example
--- bar: example
--- baz: example
===
--- foo: example
--- bar: example
--- baz: example
Loaded suite spec_type_hash_test
Started
..
Finished in 0.001326 seconds.
2 tests, 6 assertions, 0 failures, 0 errors
r11
run_tests が無くても test が走るように。つかなんだ。class 作らないでも test 走るようにすべきかどうすべきか。。
require 'test/base'
class RunEvalTest < Test::Base
end
__END__
===
--- run_eval eval
assert true
Loaded suite run_eval_test
Started
.
Finished in 0.000875 seconds.
1 tests, 1 assertions, 0 failures, 0 errors
これはひどい
http://rubyforge.org/users/gorou/
すかっりわすれてたこのアカどうすんべ。。
autotest でしょでしょ?
ZenTest に含まれる autotest だが、rails + autotest の方法以外さっぱり解らなかったのでソース読んだ。
で、autotest は カレントディレクトリの .autotest もしくは ~/.autotest があったら読み込む事が解った。んでそこで様々なところに hook かけるプラグインなどをロードできる。例えば require 'autotest/html_report' とか。詳しくは example_dot_autotest.rb を。
また、rails じゃない場合、自動で lib/*.rb と test/test_*.rb をみてくれて実行してくれる。で、これは後者がくせ者で、普通 test/test_*.rb という名前にはせずに、test/*_test.rb とテスト名はつける(ハズ)。なので .autoload を起動時に読み込むことを利用し、quick hack して .autoload に↓の書いておくと、test/*_test.rb も autotest 対象に入ってウマー、と。これでライブラリのテストも autotest れるように><。あと autotest -h 見ると解るけど、各種バージョン管理システムを定期的にアップデート(svn up とか)してくれる機能もついており、共同で開発してるときに便利かもしれない。
class Autotest
alias __tests_for_file tests_for_file
def tests_for_file(filename)
case filename
when /^lib\/.*\.rb$/ then
impl = File.basename(filename).gsub '_', '_?'
@files.keys.select do |k|
k =~ %r%^test/.*#{impl}$%
end
when /^test\/.*_test\.rb$/ then
[filename]
else
@output.puts "Dunno! #{filename}" if $TESTING
[]
end
end
end