昨今は継続的インテグレーション(CI)が大ブームです。
そしてオープンソースのプロジェクトならTravis CIを使うことで簡単にCIを始めることができます。
という訳でこのビッグウェーブに乗るしかありません。
それも Vim プラグイン開発で。
しかし、
という割と面倒臭い問題があります。
しかしもう2013年です。
Vim プラグイン開発でも CI したいお年頃です。
一体どうすれば良いのでしょうか。
幸いなことにもう2013年です。
なので以下のステップをこなせば
Vim プラグイン開発でも簡単に CI できます:
Travis CI で CI するにせよローカル環境で CI するにせよ、
テストを実行するためのツールが必要です。
まずは必要なツールをインストールするための Gemfile
を作成してコミットしましょう:
source 'https://rubygems.org'
gem 'vim-flavor', '~> 1.1'
Gemfile
を作成した後は
bundle install
でツールのインストールは完了です。
人間は細かい手順なんていちいち覚えてられません。
という訳でテストの実行手順をまとめた Rakefile
を作成してコミットしましょう:
#!/usr/bin/env rake
task :ci => [:dump, :test]
task :dump do
sh 'vim --version'
end
task :test do
sh 'bundle exec vim-flavor test'
end
Rakefile
を作成した後は
rake test
でテストの実行ができます。ci
は Travis CI での実行結果に参考情報を出力するものなのでここでは無視してください。
Travis CI は様々な言語に対応しており、
割りと何でも CI できるのですが、
その代償として多少の設定を記述する必要があります。
という訳で Travis CI で Vim プラグインのテストを実行する設定を .travis.yml
に保存してコミットしましょう:
language: ruby
rvm:
- 1.9.3
script: rake ci
(テスト対象のプラグインが他のプラグインを利用しない場合はこのステップは飛ばしてください)
世の Vim プラグインの大半は独立した存在ですが、
ものによっては他のライブラリ的なプラグインを利用しているプラグインも存在します。
例えば vim-textobj-function は関数単位で編集を行うためのテキストオブジェクトを提供しますが、テキストオブジェクトの定義はぶっちゃけ色んなエッジケースがあって面倒臭いことこの上ないので、 vim-textobj-user を利用することでその面倒臭い部分に蓋をしています。
なので vim-textobj-function のテストをするためには vim-textobj-user が必要です。
しかも
のように依存関係の上に互換性も考慮しなければありません。
しかしこのような問題についてはツールが面倒を看てくれるので問題ありません。
という訳で依存するプラグインとそのバージョンの宣言を VimFlavor
に保存してコミットしましょう。例えば vim-textobj-function なら vim-textobj-user 0.3 以降(ただし1.x 以降は除く)に依存しているので、以下のように記述します:
flavor 'kana/vim-textobj-user', '~> 0.3'
(Vim プラグインの依存関係の記述方法の詳細 についてはドキュメントを参照してください)
Vim プラグインに対するテストなので Vim に関する細かい操作を記述する必要があります。
という訳でテストは Vim script で記述するのが一番です(かなり特殊なテストなら別ですが、その対応方法は後日書きます)。
ただ Vim script で一からテストを書こうとするとかなり辛い戦いになるので既存のツールを使いましょう。
これまでのステップに従っていれば vim-vspec が自動的に使える状態になっています。
なので、
t
という名前のディレクトリを作る。.vim
にして t
の中に保存する。というルールを守れば割りと RSpec っぽい感じでテストを書くことができます。
具体例は vim-textobj-function のテスト や vim-vspec 自身のテスト を参照してください。イメージとしては大体以下のような感じです:
describe ':Expect'
it 'succeeds if an actual value matches to an expected value'
let something = 'foo'
Expect something ==# 'foo'
end
end