Logo: Relish

  1. Sign up
  2. Sign in

Project: RSpec Expectations 3.3

`output` matcher

The output matcher provides a way to assert that the block has emitted content to either
$stdout or $stderr.

With no arg, passes if the block outputs to_stdout or to_stderr. With a string, passes
if the blocks outputs that specific string to_stdout or to_stderr. With a regexp or
matcher, passes if the blocks outputs a string to_stdout or to_stderr that matches.

Note: to_stdout and to_stderr work by temporarily replacing $stdout or $stderr, so
they're not able to intercept stream output that explicitly uses STDOUT/STDERR or that
uses a reference to $stdout/$stderr that was stored before the matcher is used.

To capture output from any spawned subprocess as well, use to_stdout_from_any_process
or to_stderr_from_any_process. Output from any process that inherits the main process's
corresponding standard stream will be captured.

Note: to_stdout_from_any_process and to_stderr_from_any_process use tempfiles to
capture output, and are thus significantly (~30x) slower than to_stdout and to_stderr.

Scenarios
output_to_stdout matcher
Given
a file named "output_to_stdout_spec.rb" with:
RSpec.describe "output.to_stdout matcher" do
  specify { expect { print('foo') }.to output.to_stdout }
  specify { expect { print('foo') }.to output('foo').to_stdout }
  specify { expect { print('foo') }.to output(/foo/).to_stdout }
  specify { expect { }.to_not output.to_stdout }
  specify { expect { print('foo') }.to_not output('bar').to_stdout }
  specify { expect { print('foo') }.to_not output(/bar/).to_stdout }

  # deliberate failures
  specify { expect { }.to output.to_stdout }
  specify { expect { }.to output('foo').to_stdout }
  specify { expect { print('foo') }.to_not output.to_stdout }
  specify { expect { print('foo') }.to output('bar').to_stdout }
  specify { expect { print('foo') }.to output(/bar/).to_stdout }
end
When
I run rspec output_to_stdout_spec.rb
Then
the output should contain all of these:
11 examples, 5 failures
expected block to output to stdout, but did not
expected block to not output to stdout, but output "foo"
expected block to output "bar" to stdout, but output "foo"
expected block to output "foo" to stdout, but output nothing
expected block to output /bar/ to stdout, but output "foo"
output_to_stderr matcher
Given
a file named "output_to_stderr.rb" with:
RSpec.describe "output_to_stderr matcher" do
  specify { expect { warn('foo') }.to output.to_stderr }
  specify { expect { warn('foo') }.to output("foo\n").to_stderr }
  specify { expect { warn('foo') }.to output(/foo/).to_stderr }
  specify { expect { }.to_not output.to_stderr }
  specify { expect { warn('foo') }.to_not output('bar').to_stderr }
  specify { expect { warn('foo') }.to_not output(/bar/).to_stderr }

  # deliberate failures
  specify { expect { }.to output.to_stderr }
  specify { expect { }.to output('foo').to_stderr }
  specify { expect { warn('foo') }.to_not output.to_stderr }
  specify { expect { warn('foo') }.to output('bar').to_stderr }
  specify { expect { warn('foo') }.to output(/bar/).to_stderr }
end
When
I run rspec output_to_stderr.rb
Then
the output should contain all of these:
11 examples, 5 failures
expected block to output to stderr, but did not
expected block to not output to stderr, but output "foo
expected block to output "bar" to stderr, but output "foo "
expected block to output "foo" to stderr, but output nothing
expected block to output /bar/ to stderr, but output "foo "
output_to_stdout_from_any_process matcher
Given
a file named "output_to_stdout_from_any_process_spec.rb" with:
RSpec.describe "output.to_stdout_from_any_process matcher" do
  specify { expect { system('printf foo') }.to output.to_stdout_from_any_process }
  specify { expect { system('printf foo') }.to output("foo").to_stdout_from_any_process }
  specify { expect { system('printf foo') }.to output(/foo/).to_stdout_from_any_process }
  specify { expect { }.to_not output.to_stdout_from_any_process }
  specify { expect { system('printf foo') }.to_not output("bar").to_stdout_from_any_process }
  specify { expect { system('printf foo') }.to_not output(/bar/).to_stdout_from_any_process }

  # deliberate failures
  specify { expect { }.to output.to_stdout_from_any_process }
  specify { expect { }.to output('foo').to_stdout_from_any_process }
  specify { expect { system('printf foo') }.to_not output.to_stdout_from_any_process }
  specify { expect { system('printf foo') }.to output('bar').to_stdout_from_any_process }
  specify { expect { system('printf foo') }.to output(/bar/).to_stdout_from_any_process }
end
When
I run rspec output_to_stdout_from_any_process_spec.rb
Then
the output should contain all of these:
11 examples, 5 failures
expected block to output to stdout, but did not
expected block to not output to stdout, but output "foo"
expected block to output "bar" to stdout, but output "foo"
expected block to output "foo" to stdout, but output nothing
expected block to output /bar/ to stdout, but output "foo"
output_to_stderr_from_any_process matcher
Given
a file named "output_to_stderr_from_any_process_spec.rb" with:
RSpec.describe "output.to_stderr_from_any_process matcher" do
  specify { expect { system('printf foo 1>&2') }.to output.to_stderr_from_any_process }
  specify { expect { system('printf foo 1>&2') }.to output("foo").to_stderr_from_any_process }
  specify { expect { system('printf foo 1>&2') }.to output(/foo/).to_stderr_from_any_process }
  specify { expect { }.to_not output.to_stderr_from_any_process }
  specify { expect { system('printf foo 1>&2') }.to_not output("bar").to_stderr_from_any_process }
  specify { expect { system('printf foo 1>&2') }.to_not output(/bar/).to_stderr_from_any_process }

  # deliberate failures
  specify { expect { }.to output.to_stderr_from_any_process }
  specify { expect { }.to output('foo').to_stderr_from_any_process }
  specify { expect { system('printf foo 1>&2') }.to_not output.to_stderr_from_any_process }
  specify { expect { system('printf foo 1>&2') }.to output('bar').to_stderr_from_any_process }
  specify { expect { system('printf foo 1>&2') }.to output(/bar/).to_stderr_from_any_process }
end
When
I run rspec output_to_stderr_from_any_process_spec.rb
Then
the output should contain all of these:
11 examples, 5 failures
expected block to output to stderr, but did not
expected block to not output to stderr, but output "foo"
expected block to output "bar" to stderr, but output "foo"
expected block to output "foo" to stderr, but output nothing
expected block to output /bar/ to stderr, but output "foo"

Last published over 2 years ago by myronmarston.