Skip to content

Commit

Permalink
Re-work the pipe interception to be a little cleaner
Browse files Browse the repository at this point in the history
Per @mattwynne's feedback, wrapping can now be done with:

    Interceptor::Pipe.wrap :stdout
    Interceptor::Pipe.unwrap! :stdout

Both methods will return the Interceptor::Pipe object such that the consumer
can then inspect the interceptor's buffer.
  • Loading branch information
R. Tyler Croy committed Apr 24, 2012
1 parent ce8b3df commit b9ce6d6
Show file tree
Hide file tree
Showing 3 changed files with 93 additions and 19 deletions.
33 changes: 33 additions & 0 deletions lib/cucumber/formatter/interceptor.rb
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,39 @@ def unwrap!
def method_missing(method, *args, &blk)
@pipe.send(method, *args, &blk)
end

def self.validate_pipe(pipe)
unless [:stdout, :stderr].include? pipe
raise ArgumentError, '#wrap only accepts :stderr or :stdout'
end
end

def self.unwrap!(pipe)
validate_pipe pipe
wrapped = nil
case pipe
when :stdout
wrapped = $stdout
$stdout = wrapped.unwrap!
when :stderr
wrapped = $stderr
$stderr = wrapped.unwrap!
end
wrapped
end

def self.wrap(pipe)
validate_pipe pipe

case pipe
when :stderr
$stderr = self.new($stderr)
return $stderr
when :stdout
$stdout = self.new($stdout)
return $stdout
end
end
end
end
end
Expand Down
11 changes: 4 additions & 7 deletions lib/cucumber/formatter/junit.rb
Original file line number Diff line number Diff line change
Expand Up @@ -27,10 +27,8 @@ def before_feature(feature)
@time = 0
# In order to fill out <system-err/> and <system-out/>, we need to
# intercept the $stderr and $stdout
@interceptedout = Interceptor::Pipe.new($stdout)
@interceptederr = Interceptor::Pipe.new($stderr)
$stdout = @interceptedout
$stderr = @interceptederr
@interceptedout = Interceptor::Pipe.wrap(:stdout)
@interceptederr = Interceptor::Pipe.wrap(:stderr)
end

def before_feature_element(feature_element)
Expand Down Expand Up @@ -59,9 +57,8 @@ def after_feature(feature)

write_file(feature_result_filename(feature.file), @testsuite.target!)

# Clean-up and reset the global pipes back to their original state
$stdout = @interceptedout.unwrap!
$stderr = @interceptederr.unwrap!
Interceptor::Pipe.unwrap! :stdout
Interceptor::Pipe.unwrap! :stderr
end

def before_background(*args)
Expand Down
68 changes: 56 additions & 12 deletions spec/cucumber/formatter/interceptor_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -9,32 +9,76 @@ module Cucumber::Formatter
pipe
end

describe '#wrap!' do
it 'should raise an ArgumentError if its not passed :stderr/:stdout' do
expect {
Interceptor::Pipe.wrap(:nonsense)
}.to raise_error(ArgumentError)

end

context 'when passed :stderr' do
before :each do
@stderr = $stdout
end

it 'should wrap $stderr' do
wrapped = Interceptor::Pipe.wrap(:stderr)
$stderr.should be_instance_of Interceptor::Pipe
$stderr.should be wrapped
end

after :each do
$stderr = @stderr
end
end

context 'when passed :stdout' do
before :each do
@stdout = $stdout
end

it 'should wrap $stdout' do
wrapped = Interceptor::Pipe.wrap(:stdout)
$stdout.should be_instance_of Interceptor::Pipe
$stdout.should be wrapped
end

after :each do
$stdout = @stdout
end
end
end

describe '#unwrap!' do
before :each do
$mockpipe = subject
@stdout = $stdout
@wrapped = Interceptor::Pipe.wrap(:stdout)
end

subject do
Interceptor::Pipe.new(pipe)
it 'should raise an ArgumentError if it wasn\'t passed :stderr/:stdout' do
expect {
Interceptor::Pipe.unwrap!(:nonsense)
}.to raise_error(ArgumentError)
end

it 'should revert $mockpipe when #unwrap! is called' do
$mockpipe.should_not be pipe
$mockpipe = subject.unwrap!
$mockpipe.should be pipe
it 'should reset $stdout when #unwrap! is called' do
interceptor = Interceptor::Pipe.unwrap! :stdout
interceptor.should be_instance_of Interceptor::Pipe
$stdout.should_not be interceptor
end

it 'should disable the pipe bypass' do
buffer = '(::)'
subject.unwrap!
Interceptor::Pipe.unwrap! :stdout

pipe.should_receive(:write).with(buffer)
subject.buffer.should_not_receive(:<<)
subject.write(buffer)
@wrapped.should_receive(:write).with(buffer)
@wrapped.buffer.should_not_receive(:<<)
@wrapped.write(buffer)
end

after :each do
$mockpipe = nil
$stdout = @stdout
end
end

Expand Down

0 comments on commit b9ce6d6

Please sign in to comment.