[newbie] assert_writes implementation

Context: I needed to teach a subclass of Test::Unit::TestCase to assert
that a particular block writes something to an output stream.

In Java, an easy way to do something like this is with a pair of
PipedOutputStream/PipedInputStream pair. So I tried the same thing in
Ruby, and the result looks bit hairy to me. Having to use multi-process
semantics to write top a buffer and then read from it is a bit over the
top. There must be some better way.

Here is my code:

def assert_writes(expectedOutput)
reader, writer = IO.pipe

 if fork
   begin
     writer.close
     output = reader.read
   ensure
     reader.close if (reader && !reader.closed?)
   end
   Process.wait
   assert_equal(expectedOutput, output)
 else
   begin
     reader.close
     yield(writer)
   ensure
     writer.close if (writer && !writer.closed?)
   end
 end

end

usage example

def test_display
assert_writes(“aaa”) {|outputStream| “aaa”.display(outputStream)}
end

Please be so kind to tell me:

  1. Is it normal to do it this way?

  2. Is it the right way to do it? I am not sure this code handles all
    exception paths correctly.

  3. Rdoc says that “IO#pipe” is not supported on all platforms. So, is
    there a portable way to do it?

Brgds,
Alexey Verkhovsky

Would StringIO help?
(http://www.ruby-doc.org/stdlib/libdoc/stringio/rdoc/index.html)

require ‘test/unit’

require ‘stringio’

class TestAssertWrite < Test::Unit::TestCase
def assert_write(expected)
io = StringIO.new
yield(io)
assert_equal(expected, io.string)
end

 def test_assert_write
   assert_raise(Test::Unit::AssertionFailedError) do
     assert_write("expected") do |output|
       output.write("bogus")
     end
   end
   assert_nothing_raised do
     assert_write("expected") do |output|
       output.write("expected")
     end
   end
 end

end

Nathaniel
Terralien, Inc.

<:((><

···

On Apr 2, 2004, at 13:06, Alexey Verkhovsky wrote:

Context: I needed to teach a subclass of Test::Unit::TestCase to
assert that a particular block writes something to an output stream.

In Java, an easy way to do something like this is with a pair of
PipedOutputStream/PipedInputStream pair. So I tried the same thing in
Ruby, and the result looks bit hairy to me. Having to use
multi-process semantics to write top a buffer and then read from it is
a bit over the top. There must be some better way.

Have you looked at StringIO?

···

Alexey Verkhovsky (alex_verk@mail.ru) wrote:

Context: I needed to teach a subclass of Test::Unit::TestCase to assert
that a particular block writes something to an output stream.

In Java, an easy way to do something like this is with a pair of
PipedOutputStream/PipedInputStream pair. So I tried the same thing in
Ruby, and the result looks bit hairy to me. Having to use multi-process
semantics to write top a buffer and then read from it is a bit over the
top. There must be some better way.


Eric Hodel - drbrain@segment7.net - http://segment7.net
All messages signed with fingerprint:
FEC2 57F1 D465 EB15 5D6E 7C11 332A 551C 796C 9F04

Nathaniel Talbott wrote:

Context: I needed to teach a subclass of Test::Unit::TestCase to
assert that a particular block writes something to an output stream.
Would StringIO help?

Yup, that’s the thing I was looking for! Thanks for enlightening me.

Alex