Skip to content

Instantly share code, notes, and snippets.

@elgalu
Last active May 9, 2019 08:39
Show Gist options
  • Select an option

  • Save elgalu/5073871 to your computer and use it in GitHub Desktop.

Select an option

Save elgalu/5073871 to your computer and use it in GitHub Desktop.

Revisions

  1. elgalu revised this gist Mar 3, 2013. 1 changed file with 10 additions and 1 deletion.
    11 changes: 10 additions & 1 deletion write_expectation.rb
    Original file line number Diff line number Diff line change
    @@ -1,6 +1,15 @@
    require 'rspec'
    require 'stringio'

    # ref: http://greyblake.com/blog/2012/12/14/custom-expectations-with-rspec/
    # Custom matcher to test text written to standard output and standard error
    #
    # @example
    # expect { $stderr.puts "Some random error" }.to write(/Some.* error/).to(:stderr)
    #
    # @example
    # expect { $stderr.puts "Some specific error" }.to write('Some specific error').to(:stderr)
    #
    # @note http://greyblake.com/blog/2012/12/14/custom-expectations-with-rspec/
    RSpec::Matchers.define :write do |message|
    chain(:to) do |io|
    @io = io
  2. elgalu created this gist Mar 3, 2013.
    64 changes: 64 additions & 0 deletions write_expectation.rb
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,64 @@
    require 'stringio'

    # ref: http://greyblake.com/blog/2012/12/14/custom-expectations-with-rspec/
    RSpec::Matchers.define :write do |message|
    chain(:to) do |io|
    @io = io
    end

    match do |block|
    output =
    case io
    when :stdout then fake_stdout(&block)
    when :stderr then fake_stderr(&block)
    else fail("Allowed values for `to` are :stdout and :stderr, got `#{io.inspect}`")
    end

    case message
    when String then output.include? message
    when Regexp then output.match message
    else fail("Allowed types for write `message` are String or Regexp, got `#{message.class}`")
    end
    end

    description do
    %Q[write #{message.inspect} to #{@io}]
    end

    def failure_message(to = 'to')
    %Q[expected #{to} #{description} but got #{@buffer.inspect}]
    end

    failure_message_for_should do
    failure_message 'to'
    end

    failure_message_for_should_not do
    failure_message 'not to'
    end

    # Fake STDERR and return a string written to it.
    def fake_stderr
    original_stderr = $stderr
    $stderr = StringIO.new
    yield
    @buffer = $stderr.string
    ensure
    $stderr = original_stderr
    end

    # Fake STDOUT and return a string written to it.
    def fake_stdout
    original_stdout = $stdout
    $stdout = StringIO.new
    yield
    @buffer = $stdout.string
    ensure
    $stdout = original_stdout
    end

    # default IO is standard output
    def io
    @io ||= :stdout
    end
    end