Merge pull request #5433 from marxarelli/feature/ui-custom-pipes

core: allow IO redirection of UI for testing
This commit is contained in:
Seth Vargo 2015-05-30 12:49:09 -07:00
commit 294b0bca41
2 changed files with 36 additions and 9 deletions

View File

@ -21,9 +21,22 @@ module Vagrant
# specific. See the implementation for more docs.
attr_accessor :opts
# @return [IO] UI input. Defaults to `$stdin`.
attr_accessor :stdin
# @return [IO] UI output. Defaults to `$stdout`.
attr_accessor :stdout
# @return [IO] UI error output. Defaults to `$stderr`.
attr_accessor :stderr
def initialize
@logger = Log4r::Logger.new("vagrant::ui::interface")
@opts = {}
@stdin = $stdin
@stdout = $stdout
@stderr = $stderr
end
def initialize_copy(original)
@ -132,7 +145,7 @@ module Vagrant
super(message)
# We can't ask questions when the output isn't a TTY.
raise Errors::UIExpectsTTY if !$stdin.tty? && !Vagrant::Util::Platform.cygwin?
raise Errors::UIExpectsTTY if !@stdin.tty? && !Vagrant::Util::Platform.cygwin?
# Setup the options so that the new line is suppressed
opts ||= {}
@ -144,11 +157,11 @@ module Vagrant
say(:info, message, opts)
input = nil
if opts[:echo]
input = $stdin.gets
if opts[:echo] || !@stdin.respond_to?(:noecho)
input = @stdin.gets
else
begin
input = $stdin.noecho(&:gets)
input = @stdin.noecho(&:gets)
# Output a newline because without echo, the newline isn't
# echoed either.
@ -206,7 +219,7 @@ module Vagrant
# Determine the proper IO channel to send this message
# to based on the type of the message
channel = type == :error || opts[:channel] == :error ? $stderr : $stdout
channel = type == :error || opts[:channel] == :error ? @stderr : @stdout
# Output! We wrap this in a lock so that it safely outputs only
# one line at a time. We wrap this in a thread because as of Ruby 2.0

View File

@ -40,23 +40,37 @@ describe Vagrant::UI::Basic do
subject.output("foo", new_line: false)
end
it "outputs to stdout" do
it "outputs to the assigned stdout" do
stdout = StringIO.new
subject.stdout = stdout
expect(subject).to receive(:safe_puts).with { |message, **opts|
expect(opts[:io]).to be($stdout)
expect(opts[:io]).to be(stdout)
true
}
subject.output("foo")
end
it "outputs to stderr for errors" do
it "outputs to stdout by default" do
expect(subject.stdout).to be($stdout)
end
it "outputs to the assigned stderr for errors" do
stderr = StringIO.new
subject.stderr = stderr
expect(subject).to receive(:safe_puts).with { |message, **opts|
expect(opts[:io]).to be($stderr)
expect(opts[:io]).to be(stderr)
true
}
subject.error("foo")
end
it "outputs to stderr for errors by default" do
expect(subject.stderr).to be($stderr)
end
end
context "#detail" do