毎回作り方を忘れてしまうので、次のためにまとめます。
gemひながたの生成
$ bundle gem samplegem -b
これでファイルが一式出てきます。--test
としなくてもrspecのテスト雛形も含まれてます。
$ cd samplegem
$ ls -1a
.
..
.git
.gitignore
.rspec
.travis.yml
Gemfile
LICENSE.txt
README.md
Rakefile
bin
exe
lib
samplegem.gemspec
spec
こんな状態です。
最初にsamplegem.gemspec
を編集しないと動きませんが、いかにもデフォルトなところだけでいいです。取り急ぎ動かすだけなら適当にdummy
とかで埋めれば動きます。
実行ファイルは、exe/samplegem
です。中身は
#!/usr/bin/env ruby
require "samplegem"
だけで処理が何も入っていません。
とりあえず、末尾にputs 'hoge'
を追記して以下のようにします。
#!/usr/bin/env ruby
require "samplegem"
puts 'hoge'
bundle install
します。
$ bundle install --path vendor/bundle
Fetching gem metadata from https://rubygems.org/..........
Fetching gem metadata from https://rubygems.org/.
Resolving dependencies...
Fetching rake 10.5.0
Installing rake 10.5.0
Using bundler 1.16.0
Fetching diff-lcs 1.3
Installing diff-lcs 1.3
Fetching rspec-support 3.7.0
Installing rspec-support 3.7.0
Fetching rspec-core 3.7.1
Installing rspec-core 3.7.1
Fetching rspec-expectations 3.7.0
Installing rspec-expectations 3.7.0
Fetching rspec-mocks 3.7.0
Installing rspec-mocks 3.7.0
Fetching rspec 3.7.0
Installing rspec 3.7.0
Using samplegem 0.1.0 from source at `.`
Bundle complete! 4 Gemfile dependencies, 9 gems now installed.
Bundled gems are installed into `./vendor/bundle`
あと実行権限がついてないのでchmod +x
ししてあげると、
$ chmod +x exe/samplegem
$ bundle exec exe/samplegem
hoge
動きます。
thorの導入
コマンドラインツールとして動かせるように、thor
を入れます。
samplegem.gemspec
に、
spec.add_dependency "thor"
を追記します。そして再度bundle install
。
これでthor
がインストールされ、コマンドラインツールとしてGemを動かせるようになります。
とりあえず、
$ bundle exec exe/samplegem hello ほげほげ
こんにちは、ほげほげさん
と、helloの後に名前を渡すと、あいさつを返すところを目指します。
以下のようにファイルを作成・編集します。
exe/samplegem
#!/usr/bin/env ruby
require "samplegem"
Samplegem::Command.start(ARGV)
lib/samplegem/command.rb
require 'samplegem'
require 'thor'
require 'samplegem/hello'
module Samplegem
class Command < Thor
desc 'hello [Name]', 'あいさつを返すよ'
def hello(name)
hello = Samplegem::Hello.new
hello.say(name)
end
end
end
lib/samplegem.rb
require "samplegem/version"
require "samplegem/command"
module Samplegem
# Your code goes here...
end
※require "samplegem/command"
を追加
lib/samplegem/hello.rb
require 'samplegem'
module Samplegem
class Hello
def say(name)
puts "こんにちは、#{name}さん"
end
end
end
動きました。
$ bundle exec exe/samplegem hello ほげほげ
こんにちは、ほげほげさん
テストがしたい
雛形に含まれるテストのサンプルはコメントアウトして、
spec/samplegem_spec.rb
RSpec.describe Samplegem do
it "has a version number" do
expect(Samplegem::VERSION).not_to be nil
end
# it "does something useful" do
# expect(false).to eq(true)
# end
end
テスト実行
$ bundle exec rake spec
Samplegem
has a version number
Finished in 0.00164 seconds (files took 0.14576 seconds to load)
1 example, 0 failures
「バージョン番号があること」というデフォルトのサンプルテストのみが通る状態です。
ここに、samplegem hello ふがふが
に対して「こんにちは、ふがふがさん」が返ることを確認するようにテストを追加していきます。
Aruba Gemの導入
https://qiita.com/miya0001/items/f0d94ae144c85483354e https://qiita.com/yohm/items/e7f7203d42c2c4e653d8
いくつか記事見ましたが、どうもコマンドラインのテストがうまくできず、
[Aruba gemでCLIのテストを支援する](https://qiita.com/tbpgr/items/41730edcdb07bb5b59ad “Aruba gemでCLIのテストを支援する”)
でようやくテストが動いたので、Arubaを使った手順で進めます。
samplegem.gemspec
に、
spec.add_development_dependency "aruba"
を追記します。そして再度bundle install
。
$ bundle install
Fetching gem metadata from https://rubygems.org/.........
Fetching gem metadata from https://rubygems.org/.
Resolving dependencies...
Using rake 10.5.0
Fetching ffi 1.9.18
Installing ffi 1.9.18 with native extensions
Fetching childprocess 0.8.0
Installing childprocess 0.8.0
Fetching contracts 0.16.0
Installing contracts 0.16.0
Fetching builder 3.2.3
Installing builder 3.2.3
Fetching backports 3.11.0
Installing backports 3.11.0
Fetching cucumber-tag_expressions 1.1.1
Installing cucumber-tag_expressions 1.1.1
Fetching gherkin 5.0.0
Installing gherkin 5.0.0
Fetching cucumber-core 3.1.0
Installing cucumber-core 3.1.0
Fetching cucumber-expressions 5.0.13
Installing cucumber-expressions 5.0.13
Fetching cucumber-wire 0.0.1
Installing cucumber-wire 0.0.1
Using diff-lcs 1.3
Fetching multi_json 1.13.1
Installing multi_json 1.13.1
Fetching multi_test 0.1.2
Installing multi_test 0.1.2
Fetching cucumber 3.1.0
Installing cucumber 3.1.0
Using rspec-support 3.7.0
Using rspec-expectations 3.7.0
Using thor 0.20.0
Fetching aruba 0.14.3
Installing aruba 0.14.3
Using bundler 1.16.0
Using rspec-core 3.7.1
Using rspec-mocks 3.7.0
Using rspec 3.7.0
Using samplegem 0.1.0 from source at `.`
Bundle complete! 5 Gemfile dependencies, 24 gems now installed.
Bundled gems are installed into `./vendor/bundle`
Post-install message from aruba:
Use on ruby 1.8.7
* Make sure you add something like that to your `Gemfile`. Otherwise you will
get cucumber > 2 and this will fail on ruby 1.8.7
gem 'cucumber', '~> 1.3.20'
With aruba >= 1.0 there will be breaking changes. Make sure to read https://github.com/cucumber/aruba/blob/master/History.md for 1.0.0
ruby 1.8.7の注意が書いてありますが関係ないので無視します。
init
を実行します。
$ bundle exec aruba init --test-framework rspec
append spec/spec_helper.rb
identical spec/support/aruba.rb
append Gemfile
spec_helper.rb
にsupportディレクトリを読みに行くように追記がされます。
spec/spec_helper.rb(追記箇所のみ)
...
$LOAD_PATH.unshift File.expand_path('../../lib', __FILE__)
if RUBY_VERSION < '1.9.3'
::Dir.glob(::File.expand_path('../support/*.rb', __FILE__)).each { |f| require File.join(File.dirname(f), File.basename(f, '.rb')) }
::Dir.glob(::File.expand_path('../support/**/*.rb', __FILE__)).each { |f| require File.join(File.dirname(f), File.basename(f, '.rb')) }
else
::Dir.glob(::File.expand_path('../support/*.rb', __FILE__)).each { |f| require_relative f }
::Dir.glob(::File.expand_path('../support/**/*.rb', __FILE__)).each { |f| require_relative f }
end
support/aruba.rb
が作成されます。
spec/support/aruba.rb
require 'aruba/rspec'
Gemfile
にも何か追記されました。
source "https://rubygems.org"
git_source(:github) {|repo_name| "https://github.com/#{repo_name}" }
# Specify your gem's dependencies in samplegem.gemspec
gemspec
gem 'aruba', '~> 0.14.3'
これでテストが書けます。
spec/samplegem_spec.rb(追記)
...
RSpec.describe 'samplegem command', type: :aruba do
context 'hello option' do
before(:each) { run('samplegem hello ふがふが') }
it { expect(last_command_started).to be_successfully_executed }
it { expect(last_command_started).to have_output("こんにちは、ふがふがさん") }
end
end
テストします。
$ bundle exec rake spec
Samplegem
has a version number
samplegem command
hello option
should be successfully executed
should have output: "こんにちは、ふがふがさん"
Finished in 0.65393 seconds (files took 0.19792 seconds to load)
3 examples, 0 failures
通りました。