テストを書く時にinputの組合せが複数あったとき、パターンを網羅した一覧を作ってくれる何かがあるとうれしいなー。それをcucumberのfeatureにそのままコピペしてガシガシとテスト書いてけたら楽だろうなぁと思ったので、Gem作ってみた。

  1. できること

YAMLにパターン書いとけばテーブル作ってくれます。

abc:
 - A
 - B
 - C

bool:
 - true
 - false

value:
 - 1
 - 10
 - 100
 - 1000
 - 1000000

これが・・・

| abc | bool  |   value |
| A   | true  |       1 |
| A   | true  |      10 |
| A   | true  |     100 |
| A   | true  |    1000 |
| A   | true  | 1000000 |
| A   | false |       1 |
| A   | false |      10 |
| A   | false |     100 |
| A   | false |    1000 |
| A   | false | 1000000 |
| B   | true  |       1 |
| B   | true  |      10 |
| B   | true  |     100 |
| B   | true  |    1000 |
| B   | true  | 1000000 |
| B   | false |       1 |
| B   | false |      10 |
| B   | false |     100 |
| B   | false |    1000 |
| B   | false | 1000000 |
| C   | true  |       1 |
| C   | true  |      10 |
| C   | true  |     100 |
| C   | true  |    1000 |
| C   | true  | 1000000 |
| C   | false |       1 |
| C   | false |      10 |
| C   | false |     100 |
| C   | false |    1000 |
| C   | false | 1000000 |

こうなる。

あとはこれをcucumberとかのfeatureファイルにシナリオテンプレートとかで組み込んであげればそれっぽくなります。

  1. 動作環境

Rubyがあれば動きます。cRubyの2.x系推奨だけど、たぶん1.xでも動くかも??

  1. インストール

まだテスト書いてないので、RubyGemsのサイトには登録してないです。 なので生インストール。

$ curl -O https://github.com/tk-hamaguchi/combination_calc/raw/master/dist/combination_calc-latest.gem
$ gem install combination_calc-latest.gem
  1. つかってみる

例えば上記のようなパターンが書いてるYAMLをpattern.ymlとしておいておいた時、引数にファイルを指定すれば表が出力されます。

$ combination_calc pattern.yml

ね、簡単でしょ?

ソースはGithub( https://github.com/tk-hamaguchi/combination_calc )に上げてるので、 気が向いたら更新します。

こないだ出したアプリコンテストで画像から動画生成をしてみたものの、一瞬で動画が終了するみたいなことがあったので、その調査がてらMacに環境を作ってみるなど。

  1. 環境

今回は底まで複雑な作業をしないのと、画像素材をサーバーに転送するのが面倒だったのでMacで実施.

アプリケーション バージョン
OS MacOS 10.9
ImageMagick 6.8.7-7
ffmpeg 1.2.4
ruby 2.1.1
RMagick 2.13.2
  1. インストール

まずはImageMagickをbrewからインストール。

$ brew install imagemagick

Warning: No developer tools installed.
You should install the Command Line Tools.
Run `xcode-select --install` to install them.
==> Installing dependencies for imagemagick: jpeg, libpng, freetype
==> Installing imagemagick dependency: jpeg
==> Downloading https://downloads.sf.net/project/machomebrew/Bottles/jpeg-8d.mavericks.bottle.tar.gz
######################################################################## 100.0%
==> Pouring jpeg-8d.mavericks.bottle.tar.gz
🍺  /usr/local/Cellar/jpeg/8d: 18 files, 780K
==> Installing imagemagick dependency: libpng
==> Downloading https://downloads.sf.net/project/machomebrew/Bottles/libpng-1.5.17.mavericks.bottle.tar.gz
######################################################################## 100.0%
==> Pouring libpng-1.5.17.mavericks.bottle.tar.gz
🍺  /usr/local/Cellar/libpng/1.5.17: 15 files, 1.0M
==> Installing imagemagick dependency: freetype
==> Downloading https://downloads.sf.net/project/machomebrew/Bottles/freetype-2.5.1.mavericks.bottle.tar.gz
######################################################################## 100.0%
==> Pouring freetype-2.5.1.mavericks.bottle.tar.gz
🍺  /usr/local/Cellar/freetype/2.5.1: 59 files, 2.7M
==> Installing imagemagick
==> Downloading https://downloads.sf.net/project/machomebrew/Bottles/imagemagick-6.8.7-7.mavericks.bottle.tar.gz
######################################################################## 100.0%
==> Pouring imagemagick-6.8.7-7.mavericks.bottle.tar.gz
🍺  /usr/local/Cellar/imagemagick/6.8.7-7: 1431 files, 20M

XCodeのCommandLineToolsが入ってないといわれたのでインストール

$ xcode-select --install                                                                                                                             (14-03-07 10:23:30)

xcode-select: note: install requested for command line developer tools

続いてffmpegをインストール

$ brew install ffmpeg

==> Installing dependencies for ffmpeg: texi2html, yasm, x264, faac, lame, xvid
==> Installing ffmpeg dependency: texi2html
==> Downloading http://download.savannah.gnu.org/releases/texi2html/texi2html-1.82.tar.gz
######################################################################## 100.0%
==> ./configure --prefix=/usr/local/Cellar/texi2html/1.82 --mandir=/usr/local/Cellar/texi2html/1.82/share/man --infodir=/usr/local/Cellar/texi2html/1.82/share/info
==> make install
🍺  /usr/local/Cellar/texi2html/1.82: 107 files, 2.2M, built in 11 seconds
==> Installing ffmpeg dependency: yasm
==> Downloading http://tortall.net/projects/yasm/releases/yasm-1.2.0.tar.gz
######################################################################## 100.0%
==> ./configure --prefix=/usr/local/Cellar/yasm/1.2.0
==> make install
🍺  /usr/local/Cellar/yasm/1.2.0: 44 files, 3.3M, built in 30 seconds
==> Installing ffmpeg dependency: x264
==> Downloading http://download.videolan.org/pub/videolan/x264/snapshots/x264-snapshot-20120812-2245-stable.tar.bz2
######################################################################## 100.0%
==> ./configure --prefix=/usr/local/Cellar/x264/r2197.4 --enable-shared
==> make install
==> Caveats
Because libx264 has a rapidly-changing API, formulae that link against
it should be reinstalled each time you upgrade x264. Examples include:
   avidemux, ffmbc, ffmpeg, gst-plugins-ugly
==> Summary
🍺  /usr/local/Cellar/x264/r2197.4: 8 files, 1.8M, built in 40 seconds
==> Installing ffmpeg dependency: faac
==> Downloading http://downloads.sourceforge.net/project/faac/faac-src/faac-1.28/faac-1.28.tar.gz
######################################################################## 100.0%
==> ./configure --prefix=/usr/local/Cellar/faac/1.28
==> make install
🍺  /usr/local/Cellar/faac/1.28: 13 files, 720K, built in 23 seconds
==> Installing ffmpeg dependency: lame
==> Downloading http://downloads.sourceforge.net/sourceforge/lame/lame-3.99.5.tar.gz
######################################################################## 100.0%
==> ./configure --prefix=/usr/local/Cellar/lame/3.99.5 --enable-nasm
==> make install
🍺  /usr/local/Cellar/lame/3.99.5: 25 files, 2.1M, built in 24 seconds
==> Installing ffmpeg dependency: xvid
==> Downloading http://fossies.org/unix/privat/xvidcore-1.3.2.tar.gz
######################################################################## 100.0%
==> ./configure --disable-assembly --prefix=/usr/local/Cellar/xvid/1.3.2
==> make
==> make install
🍺  /usr/local/Cellar/xvid/1.3.2: 9 files, 1.3M, built in 21 seconds
==> Installing ffmpeg
==> Downloading http://ffmpeg.org/releases/ffmpeg-1.2.4.tar.bz2
######################################################################## 100.0%
==> Patching
patching file libavfilter/vf_drawtext.c
==> ./configure --prefix=/usr/local/Cellar/ffmpeg/1.2.4 --enable-shared --enable-pthreads --enable-gpl --enable-version3 --enable-nonfree --enable-hardcoded-tables --ena
==> make install
🍺  /usr/local/Cellar/ffmpeg/1.2.4: 147 files, 26M, built in 3.7 minutes

これだけで入るとか楽な時代になったなぁ( ̄▽ ̄;

続けてrmagickをインストール。スイッチが楽なのでrvmを利用してます。

$ gem install rmagick -v '2.13.2' --no-rdoc --no-ri

Building native extensions.  This could take a while...
Successfully installed rmagick-2.13.2
1 gem installed

もしうまく行かない時はPKG_CONFIG_PATHを指定する。 パスは上記でインストールされたImageMagickのパスを一部に利用する

$ export PKG_CONFIG_PATH=/opt/local/lib/pkgconfig:/usr/local/Cellar/imagemagick/6.8.7-7/lib/pkgconfig/:$PKG_CONFIG_PATH

これで環境構築は完了。

  1. 変換

今回は下記のフォルダ構成のファイルを想定します。

images/
  + IMG_0001.jpg
  + IMG_0002.jpg
  + IMG_0003.jpg
  + IMG_0004.jpg
  + IMG_0005.jpg
  + IMG_0006.jpg
  + IMG_0007.jpg
  + IMG_0008.jpg
  + IMG_0009.jpg
  + IMG_0010.jpg

エディタで下記のようにコードを書きます

```ruby image2movie.rb #!/usr/bin/env ruby

require ‘rubygems’ require ‘rmagick’

image_list = Magick::ImageList.new(Dir.glob(‘images/IMG_.jpg’)) image_list.delay = 50 image_list.write(‘output.mp4’)


実行したらoutput.mp4が生成されます

```sh
$ ruby image2movie.rb
  1. チューニング

動画を画像にする際のフレームレートは、Magick::ImageListインスタンスの#delay=と#ticks_per_second=で決定されます。

Magick::ImageList#ticks_per_second=は1秒間に何フレーム入れるか?というパラメータっぽく観えたけど、ticks_per_second=1にしても1fpsにならないのでたぶんうちの理解が間違ってるんだろう。 デフォルトは100になっているので、これを基準にMagick::ImageList#delay=を設定していきます。

Magick::ImageList#delay=とfpsの対応は下記の通り

delayの値 fps
1000 0.1
200 0.5
100 1
50 2
20 5
10 10

上記のコードではdelay=50にしているので、生成されるmp4では1秒間に2枚の画像が表示されるはずです。

最近ハッカソンやらアプリコンテストやらでちらほら開発してるんだけど、その中でちらほら本番環境にデプロイしたら・・・あれ?みたいなことがちょこちょこ起きてるので、短期間で効率よく試験できる環境を作ろうと思って今更ながらVagrant使ってみた。まずは仮想サーバーを立ててログインする所まで。

  1. 環境

いつも持ち歩いてるのはMacbookAirで、開発してるのはその上でVirtualBoxを使って動かしてるCentOS。今回はさらにその上にVirtualBoxを重ねるVonVの構成。ホントはMacのVirtualBoxをサーバー的に叩けるのがいいんだろうけど、まぁきっとそのうちAWSに切り替えるだろうと思って今回はこの構成でトライ。

アプリケーション バージョン
HostOS CentOS 6.5 64bit
Vagrant 1.4.3
VirtualBox 4.3
  1. 依存ライブラリのインストール

VirtualBoxはDKMS(Dynamic Kernel Module Support)を使っているらしいのでインストール


$ sudo yum install dkms

Loaded plugins: fastestmirror, presto, refresh-packagekit
Loading mirror speeds from cached hostfile
 * base: www.ftp.ne.jp
 * epel: ftp.jaist.ac.jp
 * extras: www.ftp.ne.jp
 * updates: www.ftp.ne.jp
Setting up Install Process
Resolving Dependencies
--> Running transaction check
---> Package dkms.noarch 0:2.2.0.3-20.el6 will be installed
--> Finished Dependency Resolution

Dependencies Resolved

=========================================================================================================================================================================
 Package                              Arch                                   Version                                          Repository                            Size
=========================================================================================================================================================================
Installing:
 dkms                                 noarch                                 2.2.0.3-20.el6                                   epel                                  75 k

Transaction Summary
=========================================================================================================================================================================
Install       1 Package(s)

Total download size: 75 k
Installed size: 209 k
Is this ok [y/N]: y
Downloading Packages:
Setting up and reading Presto delta metadata
Processing delta metadata
Package(s) data still to download: 75 k
dkms-2.2.0.3-20.el6.noarch.rpm                                                                                                                    |  75 kB     00:00     
Running rpm_check_debug
Running Transaction Test
Transaction Test Succeeded
Running Transaction
  Installing : dkms-2.2.0.3-20.el6.noarch                                                                                                                            1/1 
  Verifying  : dkms-2.2.0.3-20.el6.noarch                                                                                                                            1/1 

Installed:
  dkms.noarch 0:2.2.0.3-20.el6                                                                                                                                           

Complete!

  1. VirtualBoxのインストール

そしてVirtualBoxをyumからインストール。 公式がリポジトリファイルを用意してくれているので、まずそれを取り込みます。

$ sudo wget http://download.virtualbox.org/virtualbox/rpm/rhel/virtualbox.repo -P /etc/yum.repos.d/

--2014-03-01 13:09:50--  http://download.virtualbox.org/virtualbox/rpm/rhel/virtualbox.repo
download.virtualbox.org をDNSに問いあわせています... 137.254.120.26
download.virtualbox.org|137.254.120.26|:80 に接続しています... 接続しました。
HTTP による接続要求を送信しました、応答を待っています... 200 OK
長さ: 256 [text/plain]
`/etc/yum.repos.d/virtualbox.repo' に保存中

100%[===============================================================================================================================>] 256         --.-K/s 時間 0s      

2014-03-01 13:09:51 (22.7 MB/s) - `/etc/yum.repos.d/virtualbox.repo' へ保存完了 [256/256]

その後本体のインストール。今回はVirtualBox 4.3を利用します。

$ sudo  yum install VirtualBox-4.3 -y

Loaded plugins: fastestmirror, presto, refresh-packagekit
Loading mirror speeds from cached hostfile
 * base: www.ftp.ne.jp
 * epel: ftp.jaist.ac.jp
 * extras: www.ftp.ne.jp
 * updates: www.ftp.ne.jp
Setting up Install Process
Resolving Dependencies
--> Running transaction check
---> Package VirtualBox-4.3.x86_64 0:4.3.8_92456_el6-1 will be installed
--> Processing Dependency: libSDL-1.2.so.0()(64bit) for package: VirtualBox-4.3-4.3.8_92456_el6-1.x86_64
--> Running transaction check
---> Package SDL.x86_64 0:1.2.14-3.el6 will be installed
--> Finished Dependency Resolution

Dependencies Resolved

=========================================================================================================================================================================
 Package                                   Arch                              Version                                         Repository                             Size
=========================================================================================================================================================================
Installing:
 VirtualBox-4.3                            x86_64                            4.3.8_92456_el6-1                               virtualbox                             73 M
Installing for dependencies:
 SDL                                       x86_64                            1.2.14-3.el6                                    base                                  193 k

Transaction Summary
=========================================================================================================================================================================
Install       2 Package(s)

Total size: 73 M
Total download size: 73 M
Installed size: 148 M
Downloading Packages:
Setting up and reading Presto delta metadata
Processing delta metadata
Package(s) data still to download: 73 M
VirtualBox-4.3-4.3.8_92456_el6-1.x86_64.rpm                                                                                                       |  73 MB     00:23     
warning: rpmts_HdrFromFdno: Header V4 DSA/SHA1 Signature, key ID 98ab5139: NOKEY
Retrieving key from http://download.virtualbox.org/virtualbox/debian/oracle_vbox.asc
Importing GPG key 0x98AB5139:
 Userid: "Oracle Corporation (VirtualBox archive signing key) <info@virtualbox.org>"
 From  : http://download.virtualbox.org/virtualbox/debian/oracle_vbox.asc
Running rpm_check_debug
Running Transaction Test
Transaction Test Succeeded
Running Transaction
  Installing : SDL-1.2.14-3.el6.x86_64                                                                                                                               1/2 
  Installing : VirtualBox-4.3-4.3.8_92456_el6-1.x86_64                                                                                                               2/2 


Creating group 'vboxusers'. VM users must be member of that group!

No precompiled module for this kernel found -- trying to build one. Messages
emitted during module compilation will be logged to /var/log/vbox-install.log.

Stopping VirtualBox kernel modules [  OK  ]
Uninstalling old VirtualBox DKMS kernel modules [  OK  ]
Trying to register the VirtualBox kernel modules using DKMS [  OK  ]
Starting VirtualBox kernel modules [  OK  ]
  Verifying  : SDL-1.2.14-3.el6.x86_64                                                                                                                               1/2 
  Verifying  : VirtualBox-4.3-4.3.8_92456_el6-1.x86_64                                                                                                               2/2 

Installed:
  VirtualBox-4.3.x86_64 0:4.3.8_92456_el6-1                                                                                                                              

Dependency Installed:
  SDL.x86_64 0:1.2.14-3.el6                                                                                                                                              

Complete!

  1. Vagrantのインストール

いよいよ本丸。Vagrantのインストール。これは本家が公開しているRPMを利用してインストールします。ラクチン〜♪

$ wget https://dl.bintray.com/mitchellh/vagrant/vagrant_1.4.3_x86_64.rpm -P /tmp/
$ sudo yum install ~/vagrant_1.4.3_x86_64.rpm

Loaded plugins: fastestmirror, presto, refresh-packagekit
Loading mirror speeds from cached hostfile
 * base: www.ftp.ne.jp
 * epel: ftp.jaist.ac.jp
 * extras: www.ftp.ne.jp
 * updates: www.ftp.ne.jp
Setting up Install Process
Examining /tmp/vagrant_1.4.3_x86_64.rpm: 1:vagrant-1.4.3-1.x86_64
Marking /tmp/vagrant_1.4.3_x86_64.rpm to be installed
Resolving Dependencies
--> Running transaction check
---> Package vagrant.x86_64 1:1.4.3-1 will be installed
--> Finished Dependency Resolution

Dependencies Resolved

=========================================================================================================================================================================
 Package                             Arch                               Version                                  Repository                                         Size
=========================================================================================================================================================================
Installing:
 vagrant                             x86_64                             1:1.4.3-1                                /vagrant_1.4.3_x86_64                              53 M

Transaction Summary
=========================================================================================================================================================================
Install       1 Package(s)

Total size: 53 M
Installed size: 53 M
Is this ok [y/N]: y
Downloading Packages:
Running rpm_check_debug
Running Transaction Test
Transaction Test Succeeded
Running Transaction
  Installing : 1:vagrant-1.4.3-1.x86_64                                                                                                                              1/1 
  Verifying  : 1:vagrant-1.4.3-1.x86_64                                                                                                                              1/1 

Installed:
  vagrant.x86_64 1:1.4.3-1                                                                                                                                               

Complete!
  1. 仮想マシンを作成

意外にさっくり行くようで所々時間かかる部分もあったり。 次はBOX(仮想マシンのテンプレートみたいなもの)を指定してダウンロードします。 今回は本家のチュートリアルどおりprecise32を利用します。

他のBOXについては Vagrantbox.es がいい感じにまとめてくれています。

$ mkdir vagrant-test
$ cd vagrant-test
$ vagrant init precise32 http://files.vagrantup.com/precise32.box

A `Vagrantfile` has been placed in this directory. You are now
ready to `vagrant up` your first virtual environment! Please read
the comments in the Vagrantfile as well as documentation on
`vagrantup.com` for more information on using Vagrant.
  1. 仮想マシンの起動

いよいよ起動! これは意外と時間かかる。

$ vagrant up

Bringing machine 'default' up with 'virtualbox' provider...
[default] Box 'precise32' was not found. Fetching box from specified URL for
the provider 'virtualbox'. Note that if the URL does not have
a box for this provider, you should interrupt Vagrant now and add
the box yourself. Otherwise Vagrant will attempt to download the
full box prior to discovering this error.
Downloading box from URL: http://files.vagrantup.com/precise32.box
Extracting box...################################################################% (Rate: /s, Estimated time remaining: ))
Successfully added box 'precise32' with provider 'virtualbox'!
[default] Importing base box 'precise32'...
[default] Matching MAC address for NAT networking...
[default] Setting the name of the VM...
[default] Clearing any previously set forwarded ports...
[default] Fixed port collision for 22 => 2222. Now on port 2200.
[default] Clearing any previously set network interfaces...
[default] Preparing network interfaces based on configuration...
[default] Forwarding ports...
[default] -- 22 => 2200 (adapter 1)
[default] Booting VM...
[default] Waiting for machine to boot. This may take a few minutes...
[default] Machine booted and ready!
[default] The guest additions on this VM do not match the installed version of
VirtualBox! In most cases this is fine, but in rare cases it can
prevent things such as shared folders from working properly. If you see
shared folder errors, please make sure the guest additions within the
virtual machine match the version of VirtualBox you have installed on
your host and reload your VM.

Guest Additions Version: 4.2.0
VirtualBox Version: 4.3
[default] Mounting shared folders...
[default] -- /vagrant

まぁワーニング出たけど起動はしてるっぽい。

  1. ログインしてみる

どうやら下記でログインできるらしい。

$ vagrant ssh
Welcome to Ubuntu 12.04 LTS (GNU/Linux 3.2.0-23-generic-pae i686)

 * Documentation:  https://help.ubuntu.com/
Welcome to your Vagrant-built virtual machine.
Last login: Fri Sep 14 06:22:31 2012 from 10.0.2.2
vagrant@precise32:~$ 

今回はとりあえず起動まで。ChefのBerkshelfと組み合わせてもっとごにょごにょできそうなので、次はCentOSのBOX作りながらちょこっとごにょごにょしてみようかな。

最近gemを作る機会がやたら多いので、これを機にGemの作り方をまとめがてら ちょっとしたGemを作ってRubyGemsで公開するための一連の流れをメモしていきます。

  1. Gemのひな形を作る

まず最初にGemファイルのひな形を作ります。 ※ hogeまたはHogeのところは適当に読み替えてください ※ コミットログ(-mの後の英語っぽいもの)も適宜書き換えてください

$ bundle gem hoge
      create  hoge/Gemfile
      create  hoge/Rakefile
      create  hoge/LICENSE.txt
      create  hoge/README.md
      create  hoge/.gitignore
      create  hoge/hoge.gemspec
      create  hoge/lib/hoge.rb
      create  hoge/lib/hoge/version.rb
Initializating git repo in /tmp/hoge
  1. ひな形を記憶する

もともとのひな形を記憶します

$ cd hoge
$ git add .
$ git commit -a -m 'first commit.'
[master (root-commit) 8e2ae2c] first commit.
 8 files changed, 100 insertions(+), 0 deletions(-)
 create mode 100644 .gitignore
 create mode 100644 Gemfile
 create mode 100644 LICENSE.txt
 create mode 100644 README.md
 create mode 100644 Rakefile
 create mode 100644 hoge.gemspec
 create mode 100644 lib/hoge.rb
 create mode 100644 lib/hoge/version.rb
  1. .gitignoreを追記する

不要なファイルをコミットしないように.gitignoreを編集します

まず下記を追記します。

``` text .gitignore vendor/bundle *.swp


次に下記を削除します

``` text .gitignore
Gemfile.lock

ここまできたらまたコミットします

$ git commit -a -m 'Modified .gitignore'
[master 8e30bfb] Modified .gitignore
 1 files changed, 2 insertions(+), 1 deletions(-)
  1. 依存ライブラリをインストール

Gemfileに対してテストに必要なライブラリ等を追記します

$ vi Gemfile

``` ruby Gemfile

下記を追記

gem ‘rake’ gem ‘yard’, require: false gem ‘redcarpet’, require: false

group :test do gem ‘rspec’, ‘~>2.12.0’ gem ‘cucumber’ gem ‘aruba’ end


rvmを使っている場合はgemsetを作っておくことをお勧めします。

``` sh
$ rvm use 1.9.3@hoge --rvmrc --create --install

bundlerを使って各種gemをインストールします

$ bundle install --path vendor/bundle
Fetching gem metadata from https://rubygems.org/.........
Fetching gem metadata from https://rubygems.org/..
Installing rake (10.0.3)
Installing ffi (1.4.0) with native extensions
Installing childprocess (0.3.8)
Installing builder (3.1.4)
Installing diff-lcs (1.1.3)
Installing json (1.7.7) with native extensions
Installing gherkin (2.11.6) with native extensions
Installing cucumber (1.2.1)
Installing rspec-expectations (2.12.1)
Installing aruba (0.5.1)
Using hoge (0.0.1) from source at /tmp/hoge
Installing redcarpet (2.2.2) with native extensions
Installing rspec-core (2.12.2)
Installing rspec-mocks (2.12.2)
Installing rspec (2.12.0)
Installing yard (0.8.4.1)
Using bundler (1.2.3)
Your bundle is complete! It was installed into ./vendor/bundle

ここまでできたらまたコミットします

$ git add .
$ git commit -a -m 'Config dependency.'
  1. 実際にビルドするテストを書く

実際にビルドするためのテストを書いてみます。 まずテストのためのディレクトリを作成します。

$ mkdir -p features/{step_definitions,support}

次にcucumber用の環境設定ファイルを作成します

$ vi features/support/env.rb

``` ruby features/support/env.rb

encoding: utf-8

require ‘rake’ require ‘aruba/cucumber’

Before do @features_root = File.expand_path(‘../../../’, FILE) @dirs = [@features_root] end


そしてfeatureとstepを作成します

``` sh
$ vi features/build.feature

``` cucumber features/build.feature

language: ja

機能: Gemのビルド

シナリオ: gemコマンドを使ったビルド 前提 プロジェクトルートにいる かつ ディレクトリ”pkg”が削除されている もし rakeタスク”build”を実行する ならば 標準出力が下記の正規表現にマッチする: “”” hoge \d.\d.\d(.\w+)? built to pkg/hoge-\d.\d.\d(.\w+)?.gem “”” かつ 終了コードが”0”である かつ ディレクトリ”pkg”が存在している かつ 下記のファイルが存在している: |pkg/hoge-0.0.1.gem|


``` sh
$ vi features/step_definitions/gem_steps.rb

``` cucumber features/step_definitions/gem_steps.rb

encoding: utf-8

前提 /^プロジェクトルートにいる$/ do pwd.strip.should == @features_root end

前提 /^ディレクトリ”(.*?)”が削除されている$/ do |path| FileUtils.rm_rf path check_directory_presence([path], false) end

もし /^rakeタスク”(.*?)”を実行する$/ do |task_name| run_simple “rake #{task_name}” end

ならば /^終了コードが”(.*?)”である$/ do |exit_status| assert_exit_status(exit_status.to_i) end

ならば /^標準出力が下記の正規表現にマッチする:$/ do |expected| assert_matching_output(expected, all_stdout) end

ならば /^ディレクトリ”(.*?)”が存在して(いる|いない)$/ do |directory,presence| check_directory_presence([directory], (presence == “いる”)) end

ならば /^下記のファイルが存在している:$/ do |files| check_file_presence(files.raw.map{|file_row| file_row[0]}, true) end


この時点でテストが失敗することを確認します。

``` sh
$ bundle exec cucumber features

# language: ja
機能: Gemのビルド

  シナリオ: gemコマンドを使ったビルド     # features/build.feature:5
    前提プロジェクトルートにいる         # features/step_definitions/gem_steps.rb:4
    かつディレクトリ"pkg"が削除されている  # features/step_definitions/gem_steps.rb:8
    もしrakeタスク"build"を実行する  # features/step_definitions/gem_steps.rb:13
      Exit status was 1 but expected it to be 0. Output:
      
      rake aborted!
      ERROR:  While executing gem ... (Gem::InvalidSpecificationException)
          "FIXME" or "TODO" is not a description
      ~/.rvm/gems/ruby-1.9.3-p385@hoge/gems/bundler-1.2.3/lib/bundler/gem_helper.rb:146:in `sh'
      ~/.rvm/gems/ruby-1.9.3-p385@hoge/gems/bundler-1.2.3/lib/bundler/gem_helper.rb:56:in `build_gem'
      ~/.rvm/gems/ruby-1.9.3-p385@hoge/gems/bundler-1.2.3/lib/bundler/gem_helper.rb:38:in `block in install'
      Tasks: TOP => build
      (See full trace by running task with --trace)
      
       (RSpec::Expectations::ExpectationNotMetError)
      ./features/step_definitions/gem_steps.rb:14:in `/^rakeタスク"(.*?)"を実行する$/'
      features/build.feature:8:in `もしrakeタスク"build"を実行する'
    ならば標準出力が下記の正規表現にマッチする: # features/step_definitions/gem_steps.rb:22
      """
      hoge \d.\d.\d(.\w+)? built to pkg/hoge-\d.\d.\d(.\w+)?.gem
      """
    かつ終了コードが"0"である         # features/step_definitions/gem_steps.rb:18
    かつディレクトリ"pkg"が存在している   # features/step_definitions/gem_steps.rb:26
    かつ下記のファイルが存在している:      # features/step_definitions/gem_steps.rb:30
      | pkg/hoge-0.0.1.gem |

Failing Scenarios:
cucumber features/build.feature:5 # Scenario: gemコマンドを使ったビルド

1 scenario (1 failed)
7 steps (1 failed, 4 skipped, 2 passed)
0m0.982s

エラーメッセージに出ている通りにhoge.gemspecにあるgem.descriptionとgem.summaryをGemの説明に書き換えます

$ vi hoge.gemspec

``` ruby hoge.gemspec gem.description = %q{Hoge hoge} gem.summary = %q{Fuga fuga}


もう一度テストを実行し、正常に終了することを確認します。

``` sh
$ bundle exec cucumber features
# language: ja
機能: Gemのビルド

  シナリオ: gemコマンドを使ったビルド     # features/build.feature:5
    前提プロジェクトルートにいる         # features/step_definitions/gem_steps.rb:4
    かつディレクトリ"pkg"が削除されている  # features/step_definitions/gem_steps.rb:8
    もしrakeタスク"build"を実行する  # features/step_definitions/gem_steps.rb:13
    ならば標準出力が下記の正規表現にマッチする: # features/step_definitions/gem_steps.rb:22
      """
      hoge \d.\d.\d(.\w+)? built to pkg/hoge-\d.\d.\d(.\w+)?.gem
      """
    かつ終了コードが"0"である         # features/step_definitions/gem_steps.rb:18
    かつディレクトリ"pkg"が存在している   # features/step_definitions/gem_steps.rb:26
    かつ下記のファイルが存在している:      # features/step_definitions/gem_steps.rb:30
      | pkg/hoge-0.0.1.gem |

1 scenario (1 passed)
7 steps (7 passed)
0m0.967s

ここまで来たらまたコミットします

$ git add .
$ git commit -a -m 'Add build features'
[master dd40ddf] Add build features
 4 files changed, 72 insertions(+), 2 deletions(-)
 create mode 100644 features/build.feature
 create mode 100644 features/step_definitions/gem_steps.rb
 create mode 100644 features/support/env.rb
  1. rakeタスクを作成する

rakeでテストとドキュメンテーションができるようにタスクを書いて行きます。

まずタスクファイルを入れるためのディレクトリを作成します

$ mkdir lib/tasks

次にcucumber用のタスクファイルを作成します

$ vi lib/tasks/cucumber.rake

``` ruby lib/tasks/cucumber.rake require ‘cucumber’ require ‘cucumber/rake/task’

Cucumber::Rake::Task.new(:features) do |t| t.cucumber_opts = “features –format pretty” end


さらにyard用のタスクファイルを作成します

``` sh
$ vi lib/tasks/yard.rake

``` ruby lib/tasks/yard.rake require ‘yard’ require ‘yard/rake/yardoc_task’

YARD::Rake::YardocTask.new do |t| t.files = [‘app/controllers//.rb’,’app/helpers/**/.rb’, ‘app/mailers//.rb’, ‘app/models//*.rb’, ‘lib//.rb’] t.options = [’–no-private’] t.options « ’–debug’ « ’–verbose’ if $trace end


最後にRakefileに下記を追記します

``` ruby Rakefile
Dir.glob(File.expand_path('../lib/tasks/*.rake', __FILE__)).each { |f| load f }

task :default => [ :features, :yard ]

実際に追加したものが動くか確認します。 下記のようになれば成功です。

$ bundle exec rake
~/.rvm/rubies/ruby-1.9.3-p385/bin/ruby -S bundle exec cucumber features --format pretty
# language: ja
機能: Gemのビルド

  シナリオ: gemコマンドを使ったビルド     # features/build.feature:5
    前提プロジェクトルートにいる         # features/step_definitions/gem_steps.rb:4
    かつディレクトリ"pkg"が削除されている  # features/step_definitions/gem_steps.rb:8
    もしrakeタスク"build"を実行する  # features/step_definitions/gem_steps.rb:13
    ならば標準出力が下記の正規表現にマッチする: # features/step_definitions/gem_steps.rb:22
      """
      hoge \d.\d.\d(.\w+)? built to pkg/hoge-\d.\d.\d(.\w+)?.gem
      """
    かつ終了コードが"0"である         # features/step_definitions/gem_steps.rb:18
    かつディレクトリ"pkg"が存在している   # features/step_definitions/gem_steps.rb:26
    かつ下記のファイルが存在している:      # features/step_definitions/gem_steps.rb:30
      | pkg/hoge-0.0.1.gem |

1 scenario (1 passed)
7 steps (7 passed)
0m1.105s
Files:           2
Modules:         1 (    1 undocumented)
Classes:         0 (    0 undocumented)
Constants:       1 (    1 undocumented)
Methods:         0 (    0 undocumented)
 0.00% documented

ここまでの作業を記録します

$ git add .
$ git commit -a -m 'Add rake tasks.'
[master 47906c7] Add rake tasks.
 3 files changed, 24 insertions(+), 0 deletions(-)
 create mode 100644 lib/tasks/cucumber.rake
 create mode 100644 lib/tasks/yard.rake
  1. ドキュメントを記述する

READMEやモジュール(Hoge)のYARDを必要に応じて記述します。

変更した後はその作業をコミットします。

$ git commit -a -m 'Add Documents.'
[master 563a5b1] Add Documents.
 4 files changed, 33 insertions(+), 33 deletions(-)
 rewrite README.md (90%)
  1. Rubygemsにサインアップします

Rubygemsのサイト( https://rubygems.org )に行き、右上にある”sign up”からユーザー登録をします

サインアップが完了したら、下記のコマンドを使ってAPIキーを取得します。

※REGISTED_HANDLEの部分は、登録したHandleを指定してください ※curlがインストールされていない場合はyum install curlでインストールしてください

$ curl -u REGISTED_HANDLE https://rubygems.org/api/v1/api_key.yaml > ~/.gem/credentials
Enter host password for user 'REGISTED_HANDLE': 登録したパスワードを入力
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
  0    56    0    56    0     0     95      0 --:--:-- --:--:-- --:--:--     0

catした時に、rubygems_api_keyに32桁の半角英数が入っていれば成功です。

$ cat ~/.gem/credentials
---
:rubygems_api_key: 1234567890abcdefghijklmnopqrstuv
  1. RubyGemsで公開します

下記のコマンドを実行することで、rubygemsで作成したGemを公開することができます。

$ bundle exec rake release
hoge 0.0.1.pre built to pkg/hoge-0.0.1.gem
Tagged v0.0.1
Pushed git commits and tags
Pushed hoge 0.0.1 to rubygems.org
  1. 公開されたGemを確認する

公開されたGemを確認するには、RubyGemsのサイト右上にある自分の名前をクリックするか、 同じく右上にあるdashbordから確認することができます。

また、下記のコマンドでインストール可能になっています。

$ gem install hoge

Gemはホントに小さいプログラムでも作成/登録できるので、ちょっとしたツールを作って試してみると良いかもしれません。 途中で出てきたbundlerやgit,yard,cucumber,arubaについてそのうちまとめて記事にします。