RSpec:创建基于regex的类似shared_example的功能

时间:2016-12-15 07:42:16

标签: ruby-on-rails ruby rspec

作为一个有趣的项目(如果有人感兴趣,可能是一个宝石),我试图实现一个基本的正则表达式匹配器(类似于Cucumber的工作方式),其语法看起来类似于shared_examples。但我很难理解RSpec的基础以及如何解决这个问题。

这就是我的想象:

RSpec.describe do
  define_example(/adds (\d+) plus (\d+) and gets (\d+)/) do |a, b, c|
    it { expect(a + b).to eq(c) }
  end

  it_behaves_like_it 'adds 1 plus 1 and gets 2'
end

这样的实现:

class RegexExample
  attr_accessor :spec_map

  def initialize
    @spec_map = []
  end

  def define_example(regex, &block)
    spec_map << [regex, block]
  end

  def it_behaves_like_it(text)
    spec_map_match = find_spec_map_match(text)

    # Perhaps this should dynamically add a `it` test
    # to the location calling it_behavies_like_it
    it spec_map_match[2] do
      spec_map_match[1].call(*spec_map_match[3])
    end
  end

  private

  def find_spec_map_match(text)
    spec_map.each do |regex, block|
      next unless (match = text.match(regex))
      return [regex, block, text, typecast_captures(match.captures)]
    end
  end

  def typecast_captures(matches)
    matches.map do |m|
      case m
        when /\A\d+\Z/
          m.to_i
        else
          m
      end
    end
  end

0 个答案:

没有答案