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



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

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



57
58
59
60
# File 'lib/mspec/matchers/output_to_fd.rb', line 57

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

#matches?(block) ⇒ Boolean



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

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?
    FileUtils.rm out.path
  end

  return true
end

#negative_failure_messageObject



62
63
64
# File 'lib/mspec/matchers/output_to_fd.rb', line 62

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