Reputation: 2764
It would be convenient to redirect STDERR
during tests. Is this possible in Crystal?
Upvotes: 1
Views: 465
Reputation: 2764
Here is one possible way (inspired from https://github.com/mosop/stdio)
dup2
is included in Libc
. dup
has to be defined. You can then capture either STDOUT or STDERR:
lib LibC
fun dup(oldfd : LibC::Int) : LibC::Int
end
def capture(origin)
close_on_exec = origin.close_on_exec?
begin
o, i = IO.pipe
dup = LibC.dup(origin.fd)
origin.reopen(i)
yield o
LibC.dup2(dup, origin.fd)
origin.close_on_exec = close_on_exec
ensure
o.close if o
i.flush if i
i.close if i
end
end
STDERR.puts "a"
capture(STDERR) { |output|
STDERR.puts "b\nc"
puts output.gets.inspect
puts output.gets.inspect
}
STDERR.puts "d"
capture(STDOUT) { |output| STDOUT.puts "this is ignored" }
puts "done"
Upvotes: 2
Reputation: 34116
There is no way of doing it with just the standard library, but there is an external library that does the low-level operation.
https://github.com/mosop/stdio
A small Crystal library for capturing standard I/O streams
Upvotes: 5