Skip to content

Commit

Permalink
Deal with the fact that user can override stdout/stderr
Browse files Browse the repository at this point in the history
See #24 for a more thorough description of what's
going on in the matrix
  • Loading branch information
JoshCheek committed Jun 29, 2014
1 parent 4246afe commit ec3e753
Show file tree
Hide file tree
Showing 2 changed files with 47 additions and 15 deletions.
29 changes: 29 additions & 0 deletions features/regression.feature
Original file line number Diff line number Diff line change
Expand Up @@ -306,3 +306,32 @@ Feature:
# !> world
"""

Scenario: A program overriding stdout/stderr
Given the file "black_hole.rb":
"""
File.open '/dev/null', 'w' do |black_hole|
STDERR = $stderr = black_hole
STDOUT = $stdout = black_hole
puts "You won't see this, it goes into the black hole"
system %q(ruby -e '$stdout.puts "stdout gets past it b/c of dumb ruby bug"')
system %q(ruby -e '$stderr.puts "stderr gets past it b/c of dumb ruby bug"')
end
"""
When I run "seeing_is_believing black_hole.rb"
Then stderr is empty
And the exit status is 0
And stdout is:
"""
File.open '/dev/null', 'w' do |black_hole| # => File
STDERR = $stderr = black_hole # => #<File:/dev/null>
STDOUT = $stdout = black_hole # => #<File:/dev/null>
puts "You won't see this, it goes into the black hole" # => nil
system %q(ruby -e '$stdout.puts "stdout gets past it b/c of dumb ruby bug"') # => true
system %q(ruby -e '$stderr.puts "stderr gets past it b/c of dumb ruby bug"') # => true
end # => true
# >> stdout gets past it b/c of dumb ruby bug
# !> stderr gets past it b/c of dumb ruby bug
"""
33 changes: 18 additions & 15 deletions lib/seeing_is_believing/the_matrix.rb
Original file line number Diff line number Diff line change
Expand Up @@ -10,28 +10,31 @@
require 'seeing_is_believing/result'
$SiB = SeeingIsBelieving::Result.new

real_stdout = STDOUT.dup
real_stderr = STDERR.dup
read_from_fake_out, write_to_fake_out = IO.pipe
read_from_fake_err, write_to_fake_err = IO.pipe
stdout_real_obj = STDOUT # the real Ruby object, but its FD is going to keep getting reopened
stderr_real_obj = STDERR
stdout_real_fd = STDOUT.dup # duped Ruby object, but with the real file descriptor
stderr_real_fd = STDERR.dup

STDOUT.reopen write_to_fake_out
STDERR.reopen write_to_fake_err
read_from_mock_out, write_to_mock_out = IO.pipe
read_from_mock_err, write_to_mock_err = IO.pipe

stdout_real_obj.reopen write_to_mock_out
stderr_real_obj.reopen write_to_mock_err

at_exit do
STDOUT.reopen real_stdout
STDERR.reopen real_stderr
write_to_fake_out.close unless write_to_fake_out.closed?
write_to_fake_err.close unless write_to_fake_err.closed?
$SiB.stdout = read_from_fake_out.read
$SiB.stderr = read_from_fake_err.read
read_from_fake_out.close
read_from_fake_err.close
stdout_real_obj.reopen stdout_real_fd
stderr_real_obj.reopen stderr_real_fd
write_to_mock_out.close unless write_to_mock_out.closed?
write_to_mock_err.close unless write_to_mock_err.closed?
$SiB.stdout = read_from_mock_out.read
$SiB.stderr = read_from_mock_err.read
read_from_mock_out.close
read_from_mock_err.close

$SiB.exitstatus ||= 0
$SiB.exitstatus = 1 if $!
$SiB.exitstatus = $!.status if $!.kind_of? SystemExit
$SiB.bug_in_sib = $! && ! $!.kind_of?(SystemExit)

real_stdout.write YAML.dump $SiB
stdout_real_fd.write YAML.dump $SiB
end

0 comments on commit ec3e753

Please sign in to comment.