summaryrefslogtreecommitdiff
path: root/spec/mspec/lib/mspec/matchers/complain.rb
blob: 22b8be17e16a58be2cf6b3773ae3733aa948b4d7 (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
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
require 'mspec/helpers/io'

class ComplainMatcher
  def initialize(complaint = nil, options = nil)
    # the proper solution is to use double splat operator e.g.
    #   def initialize(complaint = nil, **options)
    # but we are trying to minimize language features required to run MSpec
    if complaint.is_a?(Hash)
      @complaint = nil
      @options = complaint
    else
      @complaint = complaint
      @options = options || {}
    end
  end

  def matches?(proc)
    @saved_err = $stderr
    @verbose = $VERBOSE
    begin
      err = $stderr = IOStub.new
      $VERBOSE = @options.key?(:verbose) ? @options[:verbose] : false
      Thread.current[:in_mspec_complain_matcher] = true
      proc.call
    ensure
      $VERBOSE = @verbose
      $stderr = @saved_err
      Thread.current[:in_mspec_complain_matcher] = false
    end

    @warning = err.to_s
    unless @complaint.nil?
      case @complaint
      when Regexp
        return false unless @warning =~ @complaint
      else
        return false unless @warning == @complaint
      end
    end

    return @warning.empty? ? false : true
  end

  def failure_message
    if @complaint.nil?
      ["Expected a warning", "but received none"]
    elsif @complaint.kind_of? Regexp
      ["Expected warning to match: #{@complaint.inspect}", "but got: #{@warning.chomp.inspect}"]
    else
      ["Expected warning: #{@complaint.inspect}", "but got: #{@warning.chomp.inspect}"]
    end
  end

  def negative_failure_message
    if @complaint.nil?
      ["Unexpected warning: ", @warning.chomp.inspect]
    elsif @complaint.kind_of? Regexp
      ["Expected warning not to match: #{@complaint.inspect}", "but got: #{@warning.chomp.inspect}"]
    else
      ["Expected warning: #{@complaint.inspect}", "but got: #{@warning.chomp.inspect}"]
    end
  end
end

module MSpecMatchers
  private def complain(complaint = nil, options = nil)
    ComplainMatcher.new(complaint, options)
  end
end