Class: MatchEach

Inherits:
Object
  • Object
show all
Defined in:
lib/match_each.rb

Defined Under Namespace

Classes: BlankEnumerableError, MatchEachError, NoBlockGivenError

Instance Method Summary collapse

Constructor Details

#initialize(options, &block) ⇒ MatchEach

Returns a new instance of MatchEach.



29
30
31
32
33
34
# File 'lib/match_each.rb', line 29

def initialize(options, &block)
  @empty_okay = (options and options[:empty])
  unless @block = block
    raise NoBlockGivenError, 'No block given. You probably need to use brackets "{...}" instead of "do...end"'
  end
end

Instance Method Details

#failure_lineObject



71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
# File 'lib/match_each.rb', line 71

def failure_line
  # find 'matches?' in statck trace
  # then move back to the first line number that is not a function call
  error_lines = []
  @error.backtrace.each do |line|
    if line[/:\d+:in\s*[`'"](.*)[`'"]\s*$/, 1] == 'matches?'
      this_library_already = false
      error_lines.reverse_each do |line|
        this_library = line =~ %r!rspec-multi-matchers/lib/match_each\.rb!
        this_library_already ||= this_library
        if this_library_already and !this_library
          return line[/^[^:]+:(\d+)/, 1]
        end
      end
    end
    error_lines.push line
  end

  nil # should not reach here
end

#failure_messageObject



92
93
94
95
96
97
98
# File 'lib/match_each.rb', line 92

def failure_message
  padding = ' ' * if @error.message =~ /expected not/ then 4 else 0 end

  ["    line: #{failure_line}",
   "  item #{@counter}: #{object_description}"
  ].map { |line| padding + line }.push(@error.message).join("\n")
end

#matches?(target) ⇒ Boolean

Returns:

  • (Boolean)


36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
# File 'lib/match_each.rb', line 36

def matches?(target)
  if target.nil?
    raise BlankEnumerableError, "Expected an enumerable object, but got nil"
  end

  if !@empty_okay && target.empty?
    raise BlankEnumerableError, "No items in the given enumerator.\nTo allow an empty enumerator pass the :empty option with a true value"
  end

  @counter = 0
  target.each do |obj|
    begin
      @block.call(obj)
    rescue RSpec::Expectations::ExpectationNotMetError => e
      @error = e
      @failure_object = obj
      return false
    end
    @counter += 1
  end
  true
end

#object_descriptionObject



59
60
61
62
63
64
65
66
67
68
69
# File 'lib/match_each.rb', line 59

def object_description
  insp = @failure_object.inspect
  return insp if insp.length < 300

  if @failure_object.respond_to?(:to_s)
    str = @failure_object.to_s
    return str if str .length < 300
  end

  insp[0..300] + ' ... '
end