A
Alexey Verkhovsky
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
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