既存のRubyのクラスの、テストコードgeneratorを作成する(1)

ちょっと機会があって、プログラムでRubyスクリプトを解析したいと思って調べています。まだまだ調査中なので中途半端な情報になってしまいますが、ご勘弁ください。
Rubyソースコードを解析するためのソフトウェアとしては、Ruby標準添付のripperと、seatle.rb (http://www.seattlerb.org/) のruby_parserが有名ですので、それらを使うことを前提に調査しています。

目的

まず、「Rubyスクリプトを解析してなにがしたいのか?」を説明しておきますね。
実装済みのRubyのクラスのクラスメソッドやインスタンスメソッドのテスト(RSpec)のひな形を自動生成したいと思っています。(できるかどうかはおいといてね。)
例えば、次のようなFooクラスがあるとします。(im、cmは、それぞれinstance methodとclass methodの略です。)

class Foo
  def im1(arg)
    if arg
      return arg
    else
      return nil
    end
  end

  def self.cm1(arg1, arg2)
    case arg1
    when "a"
      return arg2
    when "A"
      return arg2.upcase
    else
      return nil
    end
  end
end

そこから次のようなテストを自動生成したいのです。

describe Foo do
  describe "#im1" do
    context "if arg" do
      # TODO:
      # return arg
    end

    context "else" do
      # TODO:
      # return nil
    end
  end

  describe ".cm1" do
    context 'arg1 === "a"' do
      # TODO:
      # return arg2
    end

    context 'arg1 === "A"' do
      # TODO:
      # return arg2.upcase
    end

    context "else" do
      # TODO:
      # return nil
    end
  end
end

ripperとruby_parserのどちらを使うのか?

さて、目的がはっきりしたので、あとはやるだけですwww
私は、ripperとruby_parserの両方共使ったことがないため、そもそも何ができるのかを調べるところからです。
ripperは、るりま (http://doc.ruby-lang.org/ja/2.0.0/library/ripper.html) がちょー詳しいです。感謝感謝。
Ripper::Filter (http://doc.ruby-lang.org/ja/2.0.0/class/Ripper=3a=3aFilter.html) を使って、ちょちょっとやれば解析できそうです。

ruby_parserはripperよりももっと簡単です。以下のようなコードでRubyスクリプトを解析して、プログラムから扱いやすい形(構文木)に変換してくれます。

require "ruby_parser"

result = RubyParser.new.parse(File.read("path/to/ruby_script"))
...

しかしながら、当たり前かもしれませんが、ripperもruby_parserもRubyスクリプト構文解析まではしてくれますが、意味までは教えてくれません。つまり、「ifがあるよ、ifの近くにargがあるよ、ifの中にreturnがあるよ、returnの近くにnilがあるよ」みたいなことは教えてくれるのですが、argがifの条件だとか、nilを返すとかの作りこみが必要なのです。

あと、ruby_parserは簡単に構文木にできるのですが、行番号は取れません。これだと困りそうなので、ripperを使うのかな〜と思ったり...

なにわともあれ、まだ調査を始めたばかりです。ゴールまでの道のりはまだまだ遠い...

(つづく...)

--- PR広告
記事を読んでくださり、ありがとうございます。もしよろしければ、この記事の著者が提供している無料のサービス「かくってる?」をお試しください。