tl;dr
上記の二つの記事を参考にさせて頂きながらサンプルの mrbgem を TDD で作ってみたのでメモ。 @matsumotory さんには超感謝。
以下、サンプル。
のアイコンが嬉しい。
memo
mruby-mrbgem-template で mrbgem の雛形を作る
mruby-mrbgem-template という mrbgem の雛形を作る mrbgem を使って雛形を作成する。mruby-mrbgem-template 自体の導入について以下をご一読下さい。
mruby-mrbgem-template を導入したら以下のような Ruby ファイルを作る。
params = { :mrbgem_name => 'mruby-sample', :license => 'MIT', :github_user => 'inokappa', :mrbgem_prefix => '../../myrepo', :class_name => 'Sample', :author => 'Yohei Kawahara', } c = MrbgemTemplate.new params c.create
このファイルを以下のように実行する。
$ ./bin/mruby create.rb
実行すると ../../myrepo
以下に mruby-sample
というファイルが生成される。
% ls -l ../../myrepo/mruby-sample total 32 -rw-r--r-- 1 kappa staff 1142 Nov 1 09:47 LICENSE -rw-r--r-- 1 kappa staff 503 Nov 1 09:47 README.md -rw-r--r-- 1 kappa staff 204 Nov 1 12:53 mrbgem.rake drwxr-xr-x 4 kappa staff 136 Nov 1 12:56 mrblib -rw-r--r-- 1 kappa staff 189 Nov 1 09:47 mruby-sample.gem drwxr-xr-x 4 kappa staff 136 Nov 1 09:47 src drwxr-xr-x 4 kappa staff 136 Nov 1 12:56 test
test を書く
以下のようなファイルが ./test/mrb_sample.rb
に生成されている。
## ## Sample Test ## assert("Sample#hello") do t = Sample.new "hello" assert_equal("hello", t.hello) end assert("Sample#bye") do t = Sample.new "hello" assert_equal("hello bye", t.bye) end assert("Sample.hi") do assert_equal("hi!!", Sample.hi) end
このファイルを以下のように書き換える。
## ## Sample Test ## assert("Sample#hello") do t = Sample.new("hello") assert_equal("Say hello", t.hello) end
初めてのテスト
(snip) # conf.gem :git => 'https://github.com/iij/mruby-io.git' # conf.gem :git => 'https://github.com/iij/mruby-dir.git' # conf.gem :git => 'https://github.com/matsumoto-r/mruby-mrbgem-template.git' # 以下を追記 conf.gem '../../myrepo/mruby-sample' conf.enable_test (snip)
以下のようにテストを実行。
$ rake clean ; rake all test
以下のようにテストがコケる。
(snip) >>> Test host <<< mrbtest - Embeddable Ruby Test ...............................................................................................................................................................................................................................................................................................................................................................................................................?............................................................................................................................................................................................?...............................................................F................................................................................................................................................................................................................................................................................................................... Skip: Module#prepend super in alias super does not currently work in aliased methods Skip: File.expand_path (with ENV) Fail: Sample#hello (mrbgems: mruby-sample) - Assertion[1] Failed: Expected to be equal Expected: "Say hello" Actual: "hello" Total: 958 OK: 957 KO: 1 Crash: 0 Time: 0.36 seconds rake aborted! (snip)
ここで怯まず mruby コードを修正する。
mruby コードの修正
テストの結果を受けて mruby のコードを修正する。mruby のコードは特に弄っていなかったので以下のような状態になっている。
class Sample def bye self.hello + " bye" end end
このコードを以下のように修正する。
class Sample def initialize(data) @data = data end def hello "Say " + @data end end
改めてテスト
$ rake clean ; rake all test
以下の通りテストが通る。
(snip) >>> Test host <<< mrbtest - Embeddable Ruby Test ...............................................................................................................................................................................................................................................................................................................................................................................................................?............................................................................................................................................................................................?................................................................................................................................................................................................................................................................................................................................................................................... Skip: Module#prepend super in alias super does not currently work in aliased methods Skip: File.expand_path (with ENV) Total: 958 OK: 958 KO: 0 Crash: 0 Time: 0.38 seconds >>> Test test <<< mrbtest - Embeddable Ruby Test ...............................................................................................................................................................................................................................................................................................................................................................................................................?.................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................. Skip: Module#prepend super in alias super does not currently work in aliased methods Total: 881 OK: 881 KO: 0 Crash: 0 Time: 0.29 seconds ............. Total: 13 OK: 13 KO: 0 Crash: 0 Time: 0.4 seconds
追加で Openweathermap にアクセスしてレスポンスを出力する実装
まずは以下のようなテストを書く。
assert("Sample#access") do t = Sample.new("bye") assert_include("Fukuoka-shi", JSON::parse(t.access("Fukuoka-shi").body)['name']) end
これは Openweathermap の API に以下のようにアクセスしてレスポンスをチェック、レスポンスに Fukuoka-shi
が含まれることを期待している。
$ curl -s 'http://api.openweathermap.org/data/2.5/weather?q=Fukuoka-shi&appid=bd82977b86bf27fb59a04b61b657fb6f'
appid=bd82977b86bf27fb59a04b61b657fb6f
はここから拝借。
追加実装をテストする前に
追加実装についてテストをする前にテストを行う為には以下の mrbgem が必要になる。
- mruby-httprequest
- mruby-json
テスト実施に際して依存している mrbgem は mrbgem.rake
ファイルに以下の通りに記載する。
MRuby::Gem::Specification.new('mruby-sample') do |spec| spec.license = 'MIT' spec.authors = 'Yohei Kawahara' spec.add_test_dependency 'mruby-httprequest' spec.add_test_dependency 'mruby-json' end
テストする
テストをする。
$ rake clean ; rake all test (snip) >>> Test host <<< mrbtest - Embeddable Ruby Test ...............................................................................................................................................................................................................................................................................................................................................................................................................?............................................................................................................................................................................................?...................................................................................................................................X.................................................................................................................................................................................................................................................................................................................. Skip: Module#prepend super in alias super does not currently work in aliased methods Skip: File.expand_path (with ENV) NoMethodError: Sample#access => undefined method 'access' for #<Sample:0x7fdda480cc20 @data="bye"> (mrbgems: mruby-sample) Total: 1025 OK: 1024 KO: 0 Crash: 1 Time: 0.47 seconds rake aborted! (snip)
当然、コケる。
mruby コードを実装する
以下のように実装する。
class Sample def initialize(data) @data = data @url = "http://api.openweathermap.org/data/2.5/weather" end def hello "Say " + @data end def access(city) http = HttpRequest.new() url = @url + '?q=' + city + '&appid=bd82977b86bf27fb59a04b61b657fb6f' http.get(url) end end
改めてテスト
$ rake clean ; rake all test (snip) >>> Test host <<< mrbtest - Embeddable Ruby Test ...............................................................................................................................................................................................................................................................................................................................................................................................................?............................................................................................................................................................................................?...................................................................................................................................................................................................................................................................................................................................................................................................................................................... Skip: Module#prepend super in alias super does not currently work in aliased methods Skip: File.expand_path (with ENV) Total: 1025 OK: 1025 KO: 0 Crash: 0 Time: 1.07 seconds >>> Test test <<< mrbtest - Embeddable Ruby Test ...............................................................................................................................................................................................................................................................................................................................................................................................................?.................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................. Skip: Module#prepend super in alias super does not currently work in aliased methods Total: 881 OK: 881 KO: 0 Crash: 0 Time: 0.29 seconds ............. Total: 13 OK: 13 KO: 0 Crash: 0 Time: 0.46 seconds
テスト通った。
Travis CI でテスト
mruby-mrbgem-template でひな形を生成すると .travis.yml
とうファイルと .travis_build_config.rb
というファイルが生成されている。それぞれの中身は以下の通り。
- .travis.yml
language: c compiler: - gcc - clang before_install: - sudo apt-get -qq update install: - sudo apt-get -qq install rake bison git gperf before_script: - cd ../ - git clone https://github.com/mruby/mruby.git - cd mruby - cp -fp ../mruby-sample/.travis_build_config.rb build_config.rb script: - make all test
- .travis_build_config.rb
MRuby::Build.new do |conf| toolchain :gcc conf.gembox 'default' conf.gem '../mruby-sample' conf.enable_test end
事前に Github にリポジトリを作成し Travis CI と連携しておいて Github に push すると...
やったー。Travis CI でもテストが通った。
残るは mgem-list への登録
作った mrbgem は以下のような YAML ファイルを書いて mgem-list にプルリクエストを投げる。(今回はサンプルなので投げない)
name: mruby-sample description: Sample author: Yohei Kawahara website: https://github.com/inokappa/mruby-sample protocol: git repository: https://github.com/inokappa/mruby-sample.git dependencies: - mruby-httprequest - mruby-json
以上
改めて
- Blog 記事を書いて下さった @matsumotory さんに感謝!
- mruby-mrbgem-template 使えばテストまで含めた mrbgem の雛形が作られるので嬉しい!