class RSpec::Rails::Api::Utils

Helper methods

Public Class Methods

check_attribute_type(type, except: []) click to toggle source
# File lib/rspec/rails/api/utils.rb, line 81
def self.check_attribute_type(type, except: [])
  keys = PARAM_TYPES.keys.reject { |key| except.include? key }
  keys.include?(type)
end
check_value_type(type, value) click to toggle source
# File lib/rspec/rails/api/utils.rb, line 30
def self.check_value_type(type, value)
  return true if type == :boolean && (value.is_a?(TrueClass) || value.is_a?(FalseClass))
  return true if type == :array && value.is_a?(Array)

  raise "Unknown type #{type}" unless PARAM_TYPES.key? type

  value.is_a? PARAM_TYPES[type][:class]
end
deep_get(hash, path) click to toggle source
# File lib/rspec/rails/api/utils.rb, line 10
def self.deep_get(hash, path)
  path.split('.').inject(hash) do |sub_hash, key|
    return nil unless sub_hash.is_a?(Hash) && sub_hash.key?(key.to_sym)

    sub_hash[key.to_sym] # rubocop:disable Lint/UnmodifiedReduceAccumulator
  end
end
deep_set(hash, path, value) click to toggle source
# File lib/rspec/rails/api/utils.rb, line 18
def self.deep_set(hash, path, value)
  path = path.split('.') unless path.is_a? Array

  return value if path.count.zero?

  current_key       = path.shift.to_sym
  hash[current_key] = {} unless hash[current_key].is_a?(Hash)
  hash[current_key] = deep_set(hash[current_key], path, value)

  hash
end
same_keys?(actual, expected) click to toggle source

rubocop:enable Metrics/CyclomaticComplexity, Metrics/MethodLength

# File lib/rspec/rails/api/utils.rb, line 76
def self.same_keys?(actual, expected)
  optional = expected.reject { |_key, value| value[:required] }.keys
  actual.symbolize_keys.keys.sort - optional == expected.keys.sort - optional
end
validate_deep_object(expected_type, expected_attributes, actual) click to toggle source

rubocop:disable Metrics/CyclomaticComplexity, Metrics/MethodLength

# File lib/rspec/rails/api/utils.rb, line 60
def self.validate_deep_object(expected_type, expected_attributes, actual)
  if %i[object array].include?(expected_type) && expected_attributes.is_a?(Hash)
    case expected_type
    when :object
      return false unless validate_object_structure actual, expected_attributes
    when :array
      actual.each do |array_entry|
        return false unless validate_object_structure array_entry, expected_attributes
      end
    end
  end

  true
end
validate_object_structure(actual, expected) click to toggle source
# File lib/rspec/rails/api/utils.rb, line 39
def self.validate_object_structure(actual, expected)
  # Check keys
  return false unless same_keys? actual, expected

  expected.each_key do |key|
    next unless expected[key][:required]

    expected_type       = expected[key][:type]
    expected_attributes = expected[key][:attributes]

    # Type
    return false unless check_value_type expected_type, actual[key.to_s]

    # Deep object ?
    return false unless validate_deep_object expected_type, expected_attributes, actual[key.to_s]
  end

  true
end