brewster1134/cli_miami

View on GitHub
lib/cli_miami/error.rb

Summary

Maintainability
A
1 hr
Test Coverage
#
# Build custom i18n error messages
#
class CliMiami::Error < StandardError
  attr_reader :message

private

  def initialize value, options, *error_keys
    options[:value] = convert_type_to_string value
    options[:allowed_values] = allowed_values options

    @message = i18n_lookup_keys(options, *error_keys) || 'Unknown Error'
  end

  # convert value from it's type, to a user friendly string
  # with core ruby objects, we create a `.to_string` method instead of changes the default `.to_s` method
  #
  # rubocop:disable Metrics/MethodLength, Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
  def convert_type_to_string value
    case value

    when Array
      value.map do |e|
        if e.nil? || e == ''
          I18n.t 'cli_miami.core.empty'
        else
          convert_type_to_string e
        end
      end.to_sentence

    when Hash
      value.map do |k, v|
        v = if v.nil? || v == ''
          I18n.t 'cli_miami.core.empty'
        else
          convert_type_to_string v
        end

        "#{k}: #{v}"
      end.to_sentence

    when Range
      "#{value.min}-#{value.max}"

    when File
      File.expand_path value

    else
      value.to_s

    end
  end
  # rubocop:enable Metrics/MethodLength, Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity

  # get allowed values based on validation details
  #
  # rubocop:disable Metrics/MethodLength
  def allowed_values options
    case options[:type]
    when :array, :hash
      if options[:value_options]
        allowed_values options[:value_options]
      else
        "#{options[:min]}-#{options[:max]}"
      end

    when :boolean
      all_boolean_values = CliMiami::BOOLEAN_TRUE_VALUES + CliMiami::BOOLEAN_FALSE_VALUES
      all_boolean_values.to_sentence

    when :fixnum, :float, :multiple_choice, :range, :string, :symbol
      "#{options[:min]}-#{options[:max]}"

    when :regexp
      options[:regexp].inspect

    else
      '?'
    end
  end
  # rubocop:enable Metrics/MethodLength

  # build an i18n dot notation string to use for lookup in the language yaml
  #
  # rubocop:disable Metrics/MethodLength
  def i18n_lookup_keys options, *error_keys
    # check for type specific error first, then look for generic errors
    i18n_lookup(
      options,
      'cli_miami',
      'errors',
      options[:type].to_s,
      *error_keys
    ) || i18n_lookup(
      options,
      'cli_miami',
      'errors',
      *error_keys
    )
  end
  # rubocop:enable Metrics/MethodLength

  # use i18n dot notation keys to lookup string
  #
  def i18n_lookup options, *keys
    i18n_string = keys.flatten.compact.each(&:to_s).join('.')

    # check if value exists, and translate it
    return unless I18n.exists? i18n_string

    # format description for i18n messages
    if options[:description]
      options[:description] = ' (' << options[:description] << ')'
    end

    I18n.t i18n_string, options
  end
end