class Blufin::YmlValidatorBase

Constants

FIELD_TYPE_ARRAY
FIELD_TYPE_BLANK
FIELD_TYPE_BOOLEAN
FIELD_TYPE_FILE
FIELD_TYPE_FLOAT
FIELD_TYPE_NESTED_DATA
FIELD_TYPE_TEXT
SECTION_MATCHES_FILENAME
SECTION_TYPE_ARRAY
SECTION_TYPE_DYNAMIC
SECTION_TYPE_FIXED

Public Instance Methods

validate(site, path, structure, error_handler, path_explicitly_defined = false) click to toggle source

Does all the common validation before handing the data-hash back to the implementing class. Any errors that occur during this phase will be added to global @yml_error array. Returns a Hash which is nothing more than a code representation of the YML data (and you can be 100% sure that it's valid). @return Hash

# File lib/core/yml/yml_validator_base.rb, line 21
def validate(site, path, structure, error_handler, path_explicitly_defined = false)

    raise RuntimeError, "'path' must be either String or Array, instead got: #{path.class}" unless path.is_a?(Array) || path.is_a?(String)
    raise RuntimeError, '@yml_structure cannot be nil.' if structure.nil?

    @site      = Blufin::SiteResolver::validate_site(site)
    @site_path = Blufin::SiteResolver::get_site_location(@site)

    @yml_structure     = structure
    @yml_error_handler = error_handler
    @yml_path          = []

    paths = path.is_a?(String) ? [path] : path

    if path_explicitly_defined
        paths.each { |p| @yml_path << p }
    else
        paths.each { |p| @yml_path << "#{Blufin::SiteResolver::get_site_location(@site)}/#{p}" }
    end

    return_yml_data

end
validate_single_file(site, file, structure, error_handler) click to toggle source

Same as above but with a single file. @return Hash

# File lib/core/yml/yml_validator_base.rb, line 47
def validate_single_file(site, file, structure, error_handler)

    raise RuntimeError, "'path' must be either String or Array, instead got: #{file.class}" unless file.is_a?(Array) || file.is_a?(String)
    raise RuntimeError, '@yml_structure cannot be nil.' if structure.nil?

    @site      = Blufin::SiteResolver::validate_site(site)
    @site_path = Blufin::SiteResolver::get_site_location(@site)

    @yml_structure     = structure
    @yml_error_handler = error_handler
    @yml_path          = []

    yml_data = validate_file_single(file)

    return if yml_data.nil?

    { file => yml_data }

end

Private Instance Methods

get_required_fields(section_data) click to toggle source

Extracts an Array of required fields - or blank Array if there are none. @return Array

# File lib/core/yml/yml_validator_base.rb, line 618
def get_required_fields(section_data)
    required_fields = []
    if section_data.is_a?(Hash)
        section_data.each do |field, data|
            required_fields << field if data.is_a?(Hash) && data[:required]
        end
    end
    required_fields
end
return_yml_data() click to toggle source

Gets a Hash of all the YML files & their content. Hash 'keys' will be the filename and the 'value' is the contents of that file. It's up to the ValidatorBase implementation to decide how to format/structure the data further. @return Hash.

# File lib/core/yml/yml_validator_base.rb, line 73
def return_yml_data
    data = {}
    return data if @yml_structure == [{}]
    @yml_path.each do |yml_path|
        Blufin::Files::create_directory(yml_path) unless Blufin::Files::path_exists(yml_path)
        Blufin::Files::get_files_in_dir(yml_path, 'yml').each do |file|
            yml_data = validate_file_single(file)
            next if yml_data.nil?
            data[file] = yml_data
        end
    end
    data
end
validate_array_internals(section_data, field_name, field_value) click to toggle source

Validates the inner data of an Array. @return void

# File lib/core/yml/yml_validator_base.rb, line 437
def validate_array_internals(section_data, field_name, field_value)
    fields_expected_inner = {}
    required_keys         = []
    optional_keys         = []
    section_data.each do |key, definition|
        if definition[:required].nil? || definition[:required]
            required_keys << key
            fields_expected_inner[key] = true
        else
            optional_keys << key
            fields_expected_inner[key] = false
        end
    end
    error = false
    if field_value.is_a?(Array)
        field_value.each do |inner_value|
            if inner_value.is_a?(Array)
                fields_validate_skip = false
                fields_actual_inner  = []
                inner_value.each do |iiv|
                    unless iiv.is_a?(Hash)
                        error = inner_value
                        break
                    end
                    inner_key = iiv.keys[0]
                    fields_actual_inner << inner_key
                    unless fields_expected_inner.keys.include?(inner_key)
                        @yml_error_handler.add_error(Blufin::YmlErrorHandler::ARRAY_KEY_ROGUE, @file, @section, field_name, inner_key)
                        fields_validate_skip = true
                    end
                    # VALIDATE REGEX (IF EXISTS)
                    if section_data[inner_key].keys.include?(:regex)
                        iiv_regex = section_data[inner_key][:regex]
                        @yml_error_handler.add_error(Blufin::YmlErrorHandler::FIELD_TEXT_REGEX, @file, @section, "#{field_name}.#{inner_key}", [iiv[inner_key], Blufin::YmlCommon::convert_regex_to_string(iiv_regex)]) unless iiv[inner_key] =~ iiv_regex
                    end
                end
                validate_expected_actual_fields(fields_expected_inner, fields_actual_inner, field_name) unless fields_validate_skip
            else
                error = inner_value
                break
            end
        end
    else
        error = field_value
    end
    @yml_error_handler.add_error(Blufin::YmlErrorHandler::ARRAY_HASHES_EXPECTED, @file, @section, field_name, "#{error.class} \xe2\x86\x92 #{error.inspect}") if error
    true
end
validate_commonalities(data, section_field, definition, file, section, field) click to toggle source

Validates that a field exists (if required). Returns TRUE when no errors, FALSE otherwise. @return boolean

# File lib/core/yml/yml_validator_base.rb, line 253
def validate_commonalities(data, section_field, definition, file, section, field)
    @definition[:required] = @definition[:required].nil? ? true : @definition[:required]
    if @definition[:required]
        if data.nil? || !data.has_key?(section_field)
            @yml_error_handler.add_error(Blufin::YmlErrorHandler::FIELD_MISSING_EMPTY, @file, @section, @field, 'Field is empty or does not exist.')
            return false
        end
    end
    true
end
validate_data_type(expected_field_type, field_name, field_value) click to toggle source

Validates the data-type. @return void

# File lib/core/yml/yml_validator_base.rb, line 488
def validate_data_type(expected_field_type, field_name, field_value)
    field = @field.nil? ? field_name : "#{@field}.#{field_name}"
    case expected_field_type
        when Blufin::YmlValidatorBase::FIELD_TYPE_ARRAY
            @yml_error_handler.add_error(Blufin::YmlErrorHandler::FIELD_INVALID_TYPE, @file, @section, field, Blufin::YmlErrorHandler::error_expected_actual('Array', "#{field_value.class} \xe2\x86\x92 #{field_value}")) unless field_value.is_a?(Array)
        when Blufin::YmlValidatorBase::FIELD_TYPE_FLOAT
            @yml_error_handler.add_error(Blufin::YmlErrorHandler::FIELD_INVALID_TYPE, @file, @section, field, Blufin::YmlErrorHandler::error_expected_actual('Float', "#{field_value.class} \xe2\x86\x92 #{field_value}")) unless field_value.is_a?(Float)
        when Blufin::YmlValidatorBase::FIELD_TYPE_TEXT
            field_value = field_value.to_s if field_value.is_a?(Float) || field_value.is_a?(Integer)
            @yml_error_handler.add_error(Blufin::YmlErrorHandler::FIELD_INVALID_TYPE, @file, @section, field, Blufin::YmlErrorHandler::error_expected_actual('String', "#{field_value.class} \xe2\x86\x92 #{field_value}")) unless field_value.is_a?(String)
        when Blufin::YmlValidatorBase::FIELD_TYPE_BLANK
            @yml_error_handler.add_error(Blufin::YmlErrorHandler::FIELD_INVALID_TYPE, @file, @section, field, Blufin::YmlErrorHandler::error_expected_actual('[blank field] | NIL', "#{field_value.class} \xe2\x86\x92 #{field_value}")) unless field_value.nil?
        else
            raise RuntimeError, "Unsupported field type: #{expected_field_type}"
    end
end
validate_definition_keys(required_keys, optional_keys, actual_keys, section, field = "\xe2\x80\x94") click to toggle source

Makes sure that the definition keys are valid. Don't have to validate for :type, :required as these apply to ALL fields and are validated differently. @return void

# File lib/core/yml/yml_validator_base.rb, line 508
def validate_definition_keys(required_keys, optional_keys, actual_keys, section, field = "\xe2\x80\x94")
    raise RuntimeError, "Expected Array, but got #{required_keys.class}" unless required_keys.is_a?(Array)
    raise RuntimeError, "Expected Array, but got #{optional_keys.class}" unless optional_keys.is_a?(Array)
    required_keys.map! { |n| n.to_s }
    optional_keys.map! { |n| n.to_s }
    actual_keys.map! { |n| n.to_s }
    definition_keys = []
    optional_keys   = required_keys + optional_keys
    actual_keys.each do |key|
        next if %w(type required).include?(key)
        definition_keys << key
        raise RuntimeError, "Definition for #{section}.#{field.gsub('|', "\xe2\x86\x92")} has unrecognized key: #{key}" unless optional_keys.include?(key)
    end
    required_keys.each do |required_key|
        raise RuntimeError, "Definition for #{section}.#{field.gsub('|', "\xe2\x86\x92")} is missing required key: #{required_key}" unless definition_keys.include?(required_key)
    end
end
validate_expected_actual_fields(expected_fields, actual_fields, field = nil) click to toggle source

Makes sure the order of the field is correct. @return void

# File lib/core/yml/yml_validator_base.rb, line 528
def validate_expected_actual_fields(expected_fields, actual_fields, field = nil)
    raise RuntimeError, "Expected Hash, but got #{expected_fields.class}" unless expected_fields.is_a?(Hash)
    raise RuntimeError, "Expected Array, but got #{actual_fields.class}" unless actual_fields.is_a?(Array)
    missing_fields  = []
    incorrect_order = false
    # Checks for missing fields (but not order)
    expected_fields.each do |field, required|
        if required && !actual_fields.include?(field)
            missing_fields << field
            break
        end
    end
    if missing_fields.any?
        ef_output = ''
        af_output = ''
        expected_fields.each do |field, required|
            ef_output += required ? "\x1B[38;5;118m:#{field} " : "\x1B[38;5;255m:#{field} "
            if actual_fields.include?(field)
                af_output += "\x1B[38;5;240m:#{field} "
            else
                af_output += (' ' * field.length) + '  '
            end
        end
        @yml_error_handler.add_error(Blufin::YmlErrorHandler::FIELD_MISSING, @file, @section, field, [
            "Expected: #{ef_output}\x1B[0m",
            "  Actual: #{af_output}\x1B[0m",
            nil
        ])
    end
    afd = actual_fields.dup
    # Check field order.
    expected_fields.each do |field, required|
        if afd[0] == field
            afd.shift
        elsif afd.include?(field)
            incorrect_order = true
            break
        end
    end
    if incorrect_order
        ef_output = ''
        af_output = ''
        expected_fields.each do |field, required|
            ef_output += ":#{field} "
        end
        actual_fields.each do |field|
            af_output += ":#{field} "
        end
        @yml_error_handler.add_error(Blufin::YmlErrorHandler::FIELD_ORDER, @file, @section, field, [
            "Expected: \x1B[38;5;255m#{ef_output}\x1B[0m",
            "  Actual: \x1B[38;5;196m#{af_output}\x1B[0m",
            nil
        ])
    end
end
validate_field(value, field_is_present) click to toggle source

Validates a single key/data pair in a section. First checks if the data even exists and it does, sends it to the appropriate field-type “handler”. @return void

# File lib/core/yml/yml_validator_base.rb, line 288
def validate_field(value, field_is_present)
    type = @definition[:type]
    raise RuntimeError, ':type must be defined for all key/data definitions.' if type.nil?
    if (value.nil? || (value.is_a?(String) && value.strip == '')) && @definition[:required]
        @yml_error_handler.add_error(Blufin::YmlErrorHandler::FIELD_MISSING_EMPTY, @file, @section, @field, 'Field is empty.')
        return
    elsif (value.nil? || (value.is_a?(String) && value.strip == '')) && !field_is_present
        return
    end
    begin
        case type
            when FIELD_TYPE_ARRAY
                validate_type_array(value)
            when FIELD_TYPE_BOOLEAN
                validate_type_boolean(value)
            when FIELD_TYPE_FILE
                validate_type_file(value)
            when FIELD_TYPE_TEXT
                validate_type_text(value)
            when FIELD_TYPE_NESTED_DATA
                validate_type_nested_data(value)
            else
                raise RuntimeError, "Unsupported field type: #{type}"
        end
    rescue => e
        Blufin::Terminal::print_exception(e)
    end
end
validate_file_single(file) click to toggle source

Validates a file. @return void

# File lib/core/yml/yml_validator_base.rb, line 89
def validate_file_single(file)
    begin
        yml_data = YAML.load_file(File.expand_path(file))
    rescue => e
        message       = e.message
        message_split = message.split('.yml): ')
        message       = message_split[1] if message_split.length == 2
        @yml_error_handler.add_error(Blufin::YmlErrorHandler::FILE_INVALID, file, nil, nil, message)
        return nil
    end
    validate_section_data(yml_data, file)
    validate_section_order(yml_data, file)
    validate_line_breaks(file)
    yml_data
end
validate_line_breaks(file) click to toggle source

Makes sure the line breaks are correct. @return void

# File lib/core/yml/yml_validator_base.rb, line 586
def validate_line_breaks(file)
    previous_was_comment    = false
    previous_was_blank_line = false
    line_count              = 0
    lines                   = Blufin::Files::read_file(file)
    lines.each_with_index do |line, idx|
        line_count = line_count + 1
        if line =~ /\A#.?/ || line =~ /\A\s{2}#.?/
            previous_was_comment    = true
            previous_was_blank_line = false
        elsif line =~ /\A[A-Za-z_\-]+:/ || line =~ /\A\s{2}(app\.|common\.|config\.|mock\.)?[A-Za-z_\-]+(\[\]|\[link\])?:/ || line =~ /\A\s{4}[A-Za-z_\-]+:/
            previous_was_comment    = false
            previous_was_blank_line = false
        elsif line == "\n"
            @yml_error_handler.add_error(Blufin::YmlErrorHandler::STYLE_MULTIPLE_BLANK_LINES, @file, nil, nil, line_count) if previous_was_blank_line
            previous_was_comment    = false
            previous_was_blank_line = true
        else
            @yml_error_handler.add_error(Blufin::YmlErrorHandler::STYLE_UNRECOGNIZED_LINE, @file, nil, nil, line_count) if previous_was_blank_line
            previous_was_comment    = false
            previous_was_blank_line = false
        end
        # Makes sure there are no trailing blank lines.
        if idx == (lines.length - 1) && line[-1, 2] == "\n"
            @yml_error_handler.add_error(Blufin::YmlErrorHandler::STYLE_TRAILING_BLANK_LINES, @file, nil, nil, line_count)
            return
        end
    end
end
validate_section_data(yml_data, file) click to toggle source

Takes the Structure file (in the form of sections) and loops through them to verify. @return void

# File lib/core/yml/yml_validator_base.rb, line 107
def validate_section_data(yml_data, file)

    @yml_structure.each do |section_definition|

        section_name = section_definition[:section_name]
        section_data = section_definition[:section_data]
        section_type = section_definition[:section_type]

        # Make sure that: section_name section_type section_data -> are present (and nothing else).
        validate_definition_keys(%w(section_name section_type section_data), %w(), section_definition.keys, section_name.nil? ? "\xe2\x80\x94" : section_name)

        @field   = nil
        @file    = file
        @section = (section_name == SECTION_MATCHES_FILENAME) ? Blufin::YmlCommon::convert_filename_to_name(file) : section_name

        begin
            data = yml_data[@section]
        rescue
            data = nil
        end

        # If section doesn't have any data..
        if (!data.is_a?(Hash) && !data.is_a?(Array)) || data.nil?
            required_fields = get_required_fields(section_data)
            if required_fields.length > 0
                required_fields.each do |required_field|
                    @yml_error_handler.add_error(Blufin::YmlErrorHandler::FIELD_MISSING_EMPTY, @file, @section, required_field, 'Field is empty or does not exist.')
                end
            end
            next
        end

        if section_type == SECTION_TYPE_FIXED
            fields_expected = {}
            fields_actual   = []
            if data.is_a?(Hash)
                data.each do |field_data|
                    fields_actual << field_data[0]
                end
            end
            section_data.each do |field, definition|
                @field      = field
                @definition = definition
                next unless validate_commonalities(data, field, definition, file, @section, @field)
                validate_field(data[@field], fields_actual.include?(field))
                fields_expected[field] = @definition[:required]
            end
            if data.is_a?(Hash)
                fields_actual.each do |field_actual|
                    # Add error if field is 'rogue' -- IE: not defined in Structure Hash.
                    @yml_error_handler.add_error(Blufin::YmlErrorHandler::FIELD_ROGUE, @file, @section, field_actual, "#{@section}.#{field_actual}") unless fields_expected.keys.include?(field_actual)
                end
            end
            validate_expected_actual_fields(fields_expected, fields_actual)
        elsif section_type == SECTION_TYPE_DYNAMIC
            # Make sure that: section_regex section_fields [section_alphabetical] -> are present (and nothing else).
            validate_definition_keys(%w(section_regex section_fields), %w(section_alphabetical), section_data.keys, section_name.nil? ? "\xe2\x80\x94" : section_name)
            section_regex = section_data[:section_regex]
            fields_order  = []
            data.each do |key, data|
                fields_order << key
                # Add error if section title does not match Regex.
                @yml_error_handler.add_error(Blufin::YmlErrorHandler::SECTION_TITLE_REGEX, @file, @section, key, [key, Blufin::YmlCommon::convert_regex_to_string(section_regex)]) unless key =~ section_regex
                fields_expected = {}
                fields_actual   = []
                if data.is_a?(Hash)
                    data.each do |data_inner|
                        fields_actual << data_inner[0]
                    end
                end
                section_data[:section_fields].each do |field, definition|
                    @field      = "#{key}|#{field}"
                    @definition = definition
                    next unless validate_commonalities(data, field, definition, file, @section, @field)
                    validate_field(((data.nil? || (!data.is_a?(Hash) && !data.is_a?(Array))) ? nil : data[field]), fields_actual.include?(field))
                    fields_expected[field] = @definition[:required]
                end
                if data.is_a?(Hash)
                    fields_actual.each do |field_actual|
                        # Add error if field is 'rogue' -- IE: not defined in Structure Hash.
                        @yml_error_handler.add_error(Blufin::YmlErrorHandler::FIELD_ROGUE, @file, @section, @field.split('|')[0], "#{@section}.#{@field.split('|')[0]}") unless fields_expected.keys.include?(field_actual)
                    end
                end
                validate_expected_actual_fields(fields_expected, fields_actual, @field.split('|')[0])
            end
            # Make sure that section keys are in Alphabetical order (if flag is set).
            if section_data[:section_alphabetical]
                fields_order.dup.sort_by(&:downcase).each_with_index do |key, idx|
                    unless key == fields_order[idx]
                        @yml_error_handler.add_error(Blufin::YmlErrorHandler::SECTION_ALPHABETICAL, @file, @section, fields_order[idx], fields_order[idx])
                        break
                    end
                end
            end
        elsif section_type == SECTION_TYPE_ARRAY
            fields_data                 = {}
            expected_array_keys         = []
            expected_array_keys_compare = {}
            section_data.each do |key, data|
                raise RuntimeError, "Expect SECTION_TYPE_ARRAY :section_data to be a Hash, but got: #{data.class}" unless data.is_a?(Hash)
                data[:required]  = data[:required].nil? ? true : data[:required]
                fields_data[key] = data
                expected_array_keys << key
                expected_array_keys_compare[key] = data[:required]
                validate_definition_keys(%w(), %w(regex), data.keys, section_name.nil? ? "\xe2\x80\x94" : section_name)
            end
            data.each do |array_of_items|
                actual_array_keys = []
                array_of_items.each do |data|
                    # CHECK THAT THIS IS AN ARRAY OF HASHES!
                    unless data.is_a?(Hash)
                        @yml_error_handler.add_error(Blufin::YmlErrorHandler::ARRAY_HASHES_EXPECTED, @file, @section, nil, array_of_items.inspect)
                        break
                    end
                    key   = data.keys[0]
                    value = data.values[0]
                    if expected_array_keys.include?(key)
                        actual_array_keys << key
                    else
                        # Add error if array-key is 'rogue' -- IE: not defined in Structure Hash.
                        @yml_error_handler.add_error(Blufin::YmlErrorHandler::ARRAY_KEY_ROGUE, @file, @section, key, "#{@section}.#{key}")
                        next
                    end
                    if value.nil? || (value.is_a?(String) && value.strip == '')
                        # Add error if array value is blank.
                        @yml_error_handler.add_error(Blufin::YmlErrorHandler::ARRAY_VALUE_BLANK, @file, @section, key, ["#{@section}.#{key}"])
                        next
                    elsif fields_data.keys.include?(:regex)
                        # Add error if section title does not match Regex.
                        regex = fields_data[key][:regex]
                        @yml_error_handler.add_error(Blufin::YmlErrorHandler::SECTION_TITLE_REGEX, @file, @section, key, [value, Blufin::YmlCommon::convert_regex_to_string(regex)]) unless value.to_s =~ regex
                    end
                    # Make sure the type is correct.
                    validate_data_type(fields_data[key][:type], key, value)
                end
                validate_expected_actual_fields(expected_array_keys_compare, actual_array_keys)
            end
        else
            raise RuntimeError, "Unrecognized :section_type: #{section_type}"
        end
    end
end
validate_section_order(yml_data, file) click to toggle source

Validates that the sections are in the correct order. @return void

# File lib/core/yml/yml_validator_base.rb, line 266
def validate_section_order(yml_data, file)
    expected_sections = []
    actual_sections   = []

    @yml_structure.each do |section_definition|
        if section_definition[:section_name] == SECTION_MATCHES_FILENAME
            expected_sections << Blufin::YmlCommon::convert_filename_to_name(@file)
        else
            expected_sections << section_definition[:section_name]
        end
    end
    begin
        yml_data.each { |data| actual_sections << data[0] }
    rescue
    end
    # Add error if the sections don't match.
    @yml_error_handler.add_error(Blufin::YmlErrorHandler::SECTION_ORDER, file, nil, nil, Blufin::YmlErrorHandler::error_expected_actual(expected_sections, actual_sections)) unless expected_sections == actual_sections
end
validate_type_array(value) click to toggle source

Validate the ARRAY field types. @return void

# File lib/core/yml/yml_validator_base.rb, line 319
def validate_type_array(value)
    if value.nil? || (value.is_a?(String) && value.strip == '')
        @yml_error_handler.add_error(Blufin::YmlErrorHandler::FIELD_CANNOT_BE_BLANK, @file, @section, @field, @field.split('|')[1])
        return
    end
    error = false
    if @definition[:section_data].nil?
        if value.is_a?(Array)
            value.each do |inner_value|
                error = true unless inner_value.is_a?(String)
            end
        else
            error = true
        end
        @yml_error_handler.add_error(Blufin::YmlErrorHandler::ARRAY_STRING_EXPECTED, @file, @section, @field, value.inspect) if error
    else
        return unless validate_array_internals(@definition[:section_data], @field, value)
    end
end
validate_type_boolean(value) click to toggle source

Validate the BOOLEAN field types. @return void

# File lib/core/yml/yml_validator_base.rb, line 341
def validate_type_boolean(value)
    validate_definition_keys(%w(), %w(), @definition.keys, @section, @field)
    return if !@definition[:required] && value.nil?
    @yml_error_handler.add_error(Blufin::YmlErrorHandler::FIELD_BOOLEAN, @file, @section, @field, Blufin::YmlErrorHandler::error_expected_actual('TRUE/FALSE', value)) unless value == true || value == false
end
validate_type_file(value) click to toggle source

Validate the FILE field types. @return void

# File lib/core/yml/yml_validator_base.rb, line 349
def validate_type_file(value)
    validate_definition_keys(%w(path), %w(path), @definition.keys, @section, @field)
    return if !@definition[:required] && value.nil?
    path = @definition[:path]
    raise RuntimeError, ':path is required for all FIELD_TYPE_FILE fields.' if path.nil?
    file_location = "#{@site_path}/#{path}/#{value}"
    @yml_error_handler.add_error(Blufin::YmlErrorHandler::FIELD_FILE, @file, @section, @field, Blufin::YmlCommon::remove_site_path(file_location, @site_path)) unless Blufin::Files::file_exists(file_location)
end
validate_type_nested_data(data) click to toggle source

Validate the TEXT (Nested) field types. @return void

# File lib/core/yml/yml_validator_base.rb, line 374
def validate_type_nested_data(data)
    validate_definition_keys(%w(section_data), %w(), @definition.keys, @section, @field)
    return if !@definition[:required] && data.nil?
    section_data = @definition[:section_data]
    if data.is_a?(Hash)
        fields_expected = {}
        fields_actual   = []
        section_data.each { |field, definition| fields_expected[field] = definition[:required] }
        data.each do |field_inner, field_value|
            unless fields_expected.keys.include?(field_inner)
                # Add error if field is 'rogue' -- IE: not defined in Structure Hash.
                @yml_error_handler.add_error(Blufin::YmlErrorHandler::FIELD_ROGUE, @file, @section, field_inner, "#{@section}.#{@field}.#{field_inner}")
                next
            end
            field_type = section_data[field_inner][:type]
            raise RuntimeError, "Field Type missing for: #{@section}.#{field_inner} \xe2\x86\x92 #{section_data.inspect}" if field_type.nil?
            # Make sure the type is correct.
            validate_data_type(field_type, field_inner, field_value)
            unless section_data[field_inner].nil?
                field_inner_name = "#{@field}.#{field_inner}"
                if section_data[field_inner][:type] == FIELD_TYPE_ARRAY
                    validate_definition_keys(%w(), %w(section_data), section_data[field_inner].keys, @section, field_inner_name)
                    if section_data[field_inner].has_key?(:section_data)
                        # If inner Array has definitions.
                        break unless validate_array_internals(section_data[field_inner][:section_data], field_inner_name, field_value)
                    else
                        # If no definitions, system expects and Array of Strings.
                        error = false
                        if field_value.is_a?(Array)
                            field_value.each do |inner_value|
                                unless inner_value.is_a?(String)
                                    error = true
                                end
                            end
                        else
                            error = true
                        end
                        @yml_error_handler.add_error(Blufin::YmlErrorHandler::ARRAY_STRING_EXPECTED, @file, @section, field_inner_name, "#{field_value.class} \xe2\x86\x92 #{field_value.inspect}") if error
                    end
                elsif section_data[field_inner][:type] == FIELD_TYPE_TEXT
                    validate_definition_keys(%w(), %w(regex), section_data[field_inner].keys, @section, field_inner_name)
                    if section_data[field_inner].keys.include?(:regex)
                        regex = section_data[field_inner][:regex]
                        @yml_error_handler.add_error(Blufin::YmlErrorHandler::SECTION_VALUE_REGEX, @file, @section, field_inner_name, [field_value, Blufin::YmlCommon::convert_regex_to_string(regex)]) unless field_value.to_s =~ regex
                    end
                else
                    validate_definition_keys(%w(), %w(), section_data[field_inner].keys, @section, field_inner_name)
                end
            end

            # TODO - MORE STUFF NEEDS TO BE DONE HERE FOR GET/POST/PATCH/DELETE STUFF...
            #        LA LA LA ...

            fields_actual << field_inner
        end
        validate_expected_actual_fields(fields_expected, fields_actual, @field)
    else
        @yml_error_handler.add_error(Blufin::YmlErrorHandler::FIELD_REQUIRES_SUB_FIELDS, @file, @section, @field, Blufin::YmlErrorHandler::error_expected_actual("#{section_data.keys.join(', ')}", "(#{data.class}) #{data}"))
    end
end
validate_type_text(value) click to toggle source

Validate the TEXT field types. @return void

# File lib/core/yml/yml_validator_base.rb, line 360
def validate_type_text(value)
    validate_definition_keys(%w(), %w(capitalized regex values), @definition.keys, @section, @field)
    return if !@definition[:required] && value.nil?
    regex  = @definition[:regex]
    values = @definition[:values]
    raise RuntimeError, "Expected Regex (or nil), instead got:#{regex.class}" unless regex.nil? || regex.is_a?(Regexp)
    raise RuntimeError, "Expected Array (or nil), instead got:#{values.class}" unless values.nil? || values.is_a?(Array)
    @yml_error_handler.add_error(Blufin::YmlErrorHandler::FIELD_TEXT_CAPITALIZED, @file, @section, @field, Blufin::YmlErrorHandler::error_expected_actual(value.upcase, value)) if @definition[:capitalized] && value != value.upcase
    @yml_error_handler.add_error(Blufin::YmlErrorHandler::FIELD_TEXT_NOT_DEFINED, @file, @section, @field, Blufin::YmlErrorHandler::error_expected_actual(values.to_s, value)) unless values.nil? || values.include?(value)
    @yml_error_handler.add_error(Blufin::YmlErrorHandler::FIELD_TEXT_REGEX, @file, @section, @field, [value, Blufin::YmlCommon::convert_regex_to_string(regex)]) unless regex.nil? || value.to_s =~ regex
end