summaryrefslogtreecommitdiff
path: root/spec/mspec/lib/mspec/runner/evaluate.rb
blob: ecf7460a90729b29886bd175451c59d656c1b74b (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
class SpecEvaluate
  include MSpecMatchers

  def self.desc=(desc)
    @desc = desc
  end

  def self.desc
    @desc ||= "evaluates "
  end

  def initialize(ruby, desc)
    @ruby = ruby.rstrip
    @desc = desc || self.class.desc
  end

  # Formats the Ruby source code for reabable output in the -fs formatter
  # option. If the source contains no newline characters, wraps the source in
  # single quotes to set if off from the rest of the description string. If
  # the source does contain newline characters, sets the indent level to four
  # characters.
  def format(ruby, newline=true)
    if ruby.include?("\n")
      lines = ruby.each_line.to_a
      if /( *)/ =~ lines.first
        if $1.size > 4
          dedent = $1.size - 4
          ruby = lines.map { |l| l[dedent..-1] }.join
        else
          indent = " " * (4 - $1.size)
          ruby = lines.map { |l| "#{indent}#{l}" }.join
        end
      end
      "\n#{ruby}"
    else
      "'#{ruby.lstrip}'"
    end
  end

  def define(&block)
    ruby = @ruby
    desc = @desc
    evaluator = self

    specify "#{desc} #{format ruby}" do
      evaluator.instance_eval(ruby)
      evaluator.instance_eval(&block)
    end
  end
end

def evaluate(str, desc=nil, &block)
  SpecEvaluate.new(str, desc).define(&block)
end