From e6f9586d83737fa089e2b6479d793f0410a3e136 Mon Sep 17 00:00:00 2001 From: Mitchell Hashimoto Date: Fri, 18 Jan 2013 12:14:40 -0800 Subject: [PATCH] New validation method on the root that returns errors --- lib/vagrant/config/v2/root.rb | 38 ++++++++++++--------- test/unit/vagrant/config/v2/root_test.rb | 43 ++++++++++++++++++++++++ 2 files changed, 65 insertions(+), 16 deletions(-) diff --git a/lib/vagrant/config/v2/root.rb b/lib/vagrant/config/v2/root.rb index 32b804108..9b8cbf1f4 100644 --- a/lib/vagrant/config/v2/root.rb +++ b/lib/vagrant/config/v2/root.rb @@ -39,24 +39,30 @@ module Vagrant end end - # Validates the configuration classes of this instance and raises an - # exception if they are invalid. If you are implementing a custom configuration - # class, the method you want to implement is {Base#validate}. This is - # the method that checks all the validation, not one which defines - # validation rules. - def validate!(env) - # Validate each of the configured classes and store the results into - # a hash. - errors = @keys.inject({}) do |container, data| - key, instance = data - recorder = ErrorRecorder.new - instance.validate(env, recorder) - container[key.to_sym] = recorder if !recorder.errors.empty? - container + # This validates the configuration and returns a hash of error + # messages by section. If there are no errors, an empty hash + # is returned. + # + # @param [Environment] env + # @return [Hash] + def validate(env) + # Go through each of the configuration keys and validate + errors = {} + @keys.each do |_key, instance| + if instance.respond_to?(:validate) + # Validate this single item, and if we have errors then + # we merge them into our total errors list. + result = instance.validate(env) + if result && !result.empty? + result.each do |key, value| + errors[key] ||= [] + errors[key] += value + end + end + end end - return if errors.empty? - raise Errors::ConfigValidationFailed, :messages => Util::TemplateRenderer.render("config/validation_failed", :errors => errors) + errors end # Returns the internal state of the root object. This is used diff --git a/test/unit/vagrant/config/v2/root_test.rb b/test/unit/vagrant/config/v2/root_test.rb index 59140af77..10b5228a0 100644 --- a/test/unit/vagrant/config/v2/root_test.rb +++ b/test/unit/vagrant/config/v2/root_test.rb @@ -31,4 +31,47 @@ describe Vagrant::Config::V2::Root do "keys" => {} } end + + describe "validation" do + let(:instance) do + map = { :foo => Object, :bar => Object } + described_class.new(map) + end + + it "should return nil if valid" do + instance.validate({}).should == {} + end + + it "should return errors if invalid" do + errors = { "foo" => ["errors!"] } + env = { "errors" => errors } + foo = instance.foo + def foo.validate(env) + env["errors"] + end + + instance.validate(env).should == errors + end + + it "should merge errors via array concat if matching keys" do + errors = { "foo" => ["errors!"] } + env = { "errors" => errors } + foo = instance.foo + bar = instance.bar + def foo.validate(env) + env["errors"] + end + + def bar.validate(env) + env["errors"].merge({ "bar" => ["bar"] }) + end + + expected_errors = { + "foo" => ["errors!", "errors!"], + "bar" => ["bar"] + } + + instance.validate(env).should == expected_errors + end + end end