Class: OutputToFDMatcher

Inherits:
Object show all
Defined in:
lib/mspec/matchers/output_to_fd.rb

Overview

Lower-level output speccing mechanism for a single output stream. Unlike OutputMatcher which provides methods to capture the output, we actually replace the FD itself so that there is no reliance on a certain method being used.

Instance Method Summary collapse

Constructor Details

#initialize(expected, to) ⇒ OutputToFDMatcher


9
10
11
12
13
14
15
16
17
18
19
20
21
22
# File 'lib/mspec/matchers/output_to_fd.rb', line 9

def initialize(expected, to)
  @to, @expected = to, expected

  case @to
  when STDOUT
    @to_name = "STDOUT"
  when STDERR
    @to_name = "STDERR"
  when IO
    @to_name = @to.object_id.to_s
  else
    raise ArgumentError, "#{@to.inspect} is not a supported output target"
  end
end

Instance Method Details

#failure_messageObject


59
60
61
62
# File 'lib/mspec/matchers/output_to_fd.rb', line 59

def failure_message()
  ["Expected (#{@to_name}): #{@expected.inspect}\n",
   "#{'but got'.rjust(@to_name.length + 10)}: #{@actual.inspect}\nBacktrace"]
end

#matches?(block) ⇒ Boolean


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
# File 'lib/mspec/matchers/output_to_fd.rb', line 24

def matches?(block)
  old_to = @to.dup
  out = File.open(tmp("mspec_output_to_#{$$}_#{Time.now.to_i}"), 'w+')

  # Replacing with a file handle so that Readline etc. work
  @to.reopen out

  block.call

ensure
  begin
    @to.reopen old_to

    out.rewind
    @actual = out.read

    case @expected
      when Regexp
        return !(@actual =~ @expected).nil?
      else
        return @actual == @expected
    end

  # Clean up
  ensure
    out.close unless out.closed?
    File.delete out.path
    if !old_to.closed? and old_to.fileno != @to.fileno # reopen might create a new fd
      old_to.close
    end
  end

  return true
end

#negative_failure_messageObject


64
65
66
# File 'lib/mspec/matchers/output_to_fd.rb', line 64

def negative_failure_message()
  ["Expected output (#{@to_name}) to NOT be:\n", @actual.inspect]
end