Skip to content
This repository has been archived by the owner on Nov 30, 2024. It is now read-only.

Commit

Permalink
Nearly support compound matchers on CaptureStreamToTempfile
Browse files Browse the repository at this point in the history
Sadly, it doesn't quite work on StdErrSplitter, because of the existing
(but possibly non-impactful?) bug around restoring the original stream
during the ensure block.
  • Loading branch information
nevinera committed May 19, 2024
1 parent 5d9ee8b commit 3ff79c5
Showing 1 changed file with 26 additions and 0 deletions.
26 changes: 26 additions & 0 deletions lib/rspec/matchers/built_in/output.rb
Original file line number Diff line number Diff line change
Expand Up @@ -188,7 +188,24 @@ def capture(block)
# thread, fileutils, etc), so it's worth delaying it until this point.
require 'tempfile'

# This is.. awkward-looking. But it's written this way because of how
# compound matchers work - we essentially need to be able to tell if
# we're in an _inner_ matcher, so we can pass the stream-output along
# to the outer matcher for further evaluation in that case. Added to
# that, it's fairly difficult to _tell_, because the only actual state
# we have access to is the stream itself, and in the case of stderr,
# that stream is really a RSpec::Support::StdErrSplitter (which is why
# we're testing `is_a?(File)` in such an obnoxious way).
inner_matcher =
(stream == STDERR && STDERR.is_a?(File)) ||
(stream == STDOUT && STDOUT.is_a?(File))

# FIXME: stream.clone isn't sufficient right now - the StdErrSplitter
# clones with the same stream, and reopening the stream on either of
# them effectively updates both. Which means that the ensure-reopen
# further down doesn't really do anything currently.
original_stream = stream.clone

captured_stream = Tempfile.new(name)

begin
Expand All @@ -198,11 +215,20 @@ def capture(block)
captured_stream.rewind
captured_stream.read
ensure
captured_content = inner_matcher ? read_contents(captured_stream) : nil
stream.reopen(original_stream)
stream.write(captured_content) if captured_content
captured_stream.close
captured_stream.unlink
end
end

private

def read_contents(strm)
strm.rewind
strm.read
end
end
end
end
Expand Down

0 comments on commit 3ff79c5

Please sign in to comment.