lib/appsent/config_value.rb in appsent-0.0.2 vs lib/appsent/config_value.rb in appsent-0.0.3

- old
+ new

@@ -5,52 +5,93 @@ WRONG_DATA_TYPE_PASSED_MSG = "data type should be ruby class!" VALUE_NOT_EXISTS_MSG = "does not exists" VALUE_WRONG_TYPE_MSG = "wrong type,should be %s" FULL_ERROR_MESSAGE = "%s: %s # %s%s%s" + WRONG_CHILD_OPTIONS_MSG = "wrong nested parameters" # data => it's an actual data of parameter def initialize parameter, data_type, data, description, example, &block @parameter, @data_type, @data, @description, @example = (parameter and parameter.to_sym), data_type, data, description, example @data_type ||= Hash raise WRONG_DATA_TYPE_PASSED_MSG unless @data_type.is_a?(Class) - raise "params #{@data_type} and block given" if block_given? and not @data_type==Hash + raise "params #{@data_type} and block given" if block_given? and not [Array,Hash].include?(@data_type) @block = block @nesting = 0 end def valid? - return @checked if defined?(@checked) - @checked = if data.instance_of?(data_type) - if @block - data.symbolize_keys! - self.instance_exec(&@block) - child_options.any? { |option| option.valid? } - else - true - end - else - false - end + return @valid if defined?(@valid) + + @valid = if data.instance_of?(data_type) + if @block + if data.is_a?(Array) + data.each do |data| + child_options << self.class.new( + @parameter, + Hash, + data, + @description, + @example, + &@block + ) + end + else + data.symbolize_keys! + self.instance_exec(&@block) + end + + @child_options_valid = child_options.ask_all? { |option| option.valid? } + else + true + end + else + false + end end def child_options @options ||= [] end + def child_options_valid? + return @child_options_valid if defined?(@child_options_valid) + true + end + def error_message + actual_data_or_example = ((data_type==Hash ? '' : data) or example) + + actual_error_msg = if child_options_valid? + (data ? VALUE_WRONG_TYPE_MSG % [data_type] : VALUE_NOT_EXISTS_MSG) + else + WRONG_CHILD_OPTIONS_MSG + end + desc = (description and "(#{description})") - actual_error_msg = (data ? VALUE_WRONG_TYPE_MSG % [data_type] : VALUE_NOT_EXISTS_MSG) + optional_type = (data ? '' : ', '+data_type.inspect) - ' '*(self.nesting+1)+FULL_ERROR_MESSAGE % [parameter, (data or example), actual_error_msg, desc, optional_type] + + @error_message = ' '*(self.nesting+1)+FULL_ERROR_MESSAGE % [parameter, actual_data_or_example, actual_error_msg, desc, optional_type] + if child_options_valid? + return @error_message + else + @error_message += "\n"+child_options.map { |o| o.valid? ? nil : o.error_message }.compact.join("\n") + end end private def method_missing option, opts={} - self.child_options << self.class.new(option.to_s, opts[:type], data[option.to_sym], opts[:desc], opts[:example]) + self.child_options << self.class.new( + option.to_s, + opts[:type], + data[option.to_sym], + opts[:desc], + opts[:example] + ) self.child_options.last.nesting+=(self.nesting+1) end end end