MultiStep should do input/output validation

This commit is contained in:
Mitchell Hashimoto 2011-12-06 18:19:18 -08:00
parent 7d3746b292
commit 73761dc92a
2 changed files with 58 additions and 0 deletions

View File

@ -67,6 +67,8 @@ module Vagrant
maps = {}
maps = extra_inputs.pop if extra_inputs.last.kind_of?(Hash)
# Go over each extra input and handle the mapping. This is typically
# syntactic sugar.
extra_inputs.each do |direct|
if direct.is_a?(Symbol)
# Symbols are assumed to be inputs to this group
@ -76,6 +78,21 @@ module Vagrant
maps[direct] = direct.variable
end
# Turn the pure symbols into mapping from last steps
maps.keys.each do |from|
if from.kind_of?(Symbol)
new_from = output(@step_names.last, from)
maps[new_from] = maps.delete(from)
end
end
# Verify that all the mappings are correctly satisfied.
maps.each do |from, to|
if !mapping_satisfied?(step_class, from, to)
raise ArgumentError, "Mapping from #{from.variable} to #{to} fails."
end
end
# Append the step
@step_names << step_name
@steps[step_name] = [step_class, maps]
@ -120,6 +137,24 @@ module Vagrant
step_outputs[name].dup
end
end
protected
def mapping_satisfied?(step, from, to)
# If the step inputs don't contain to then we fail
return false if !step.inputs.include?(to)
if from.kind_of?(GroupInput)
# We assume that inputs from the group are satisfied since
# it has to come in.
return true
elsif from.kind_of?(StepOutput)
# Verify that the outputs of the step exist to map.
return @steps[from.name][0].outputs.include?(from.variable)
end
true
end
end
end
end

View File

@ -136,4 +136,27 @@ describe Vagrant::Action::MultiStep do
g = described_class.new
expect { g.step :foo }.to raise_error(ArgumentError)
end
it "should not allow remapping from outputs that don't exist" do
step_A = Class.new(Vagrant::Action::Step) do
output :output_A
end
step_B = Class.new(Vagrant::Action::Step) do
input :input_B
end
g = described_class.new
g.step step_A
expect { g.step step_B, :output_B => :input_B }.to raise_error(ArgumentError)
end
it "should not allow remapping to inputs that don't exist" do
step_A = Class.new(Vagrant::Action::Step) do
input :input_A
end
g = described_class.new
expect { g.step step_A, g.input(:foo) => :input_B }.to raise_error(ArgumentError)
end
end