module Pragma::Macro::Classes

Public Class Methods

for(input, options) click to toggle source
# File lib/pragma/macro/classes.rb, line 12
def for(input, options)
  {
    'model.class' => expected_model_class(input, options),
    'policy.default.class' => expected_policy_class(input, options),
    'policy.default.scope.class' => expected_policy_scope_class(input, options),
    'decorator.instance.class' => expected_instance_decorator_class(input, options),
    'decorator.collection.class' => expected_collection_decorator_class(input, options),
    'contract.default.class' => expected_contract_class(input, options)
  }.each_pair do |key, value|
    next if options[key]

    # FIXME: This entire block is required to trigger Rails autoloading. Ugh.
    begin
      Object.const_get(value)
    rescue NameError => e
      # We check the error message to avoid silently ignoring other NameErrors
      # thrown while initializing the constant.
      raise e unless e.message.start_with?('uninitialized constant')

      # Required instead of a simple equality check because loading
      # API::V1::Post::Contract::Index might throw "uninitialized constant
      # API::V1::Post::Contract" if the resource has no contracts at all.
      error_constant = e.message.scan(/uninitialized constant ([^\s]+)/).first.first
      raise e unless value.sub(/\A::/, '').start_with?(error_constant)
    end

    options[key] = (Object.const_get(value) if Object.const_defined?(value))
  end
end

Private Class Methods

expected_collection_decorator_class(input, options) click to toggle source
# File lib/pragma/macro/classes.rb, line 83
def expected_collection_decorator_class(input, options)
  [
    resource_namespace(input, options),
    'Decorator',
    'Collection'
  ].join('::')
end
expected_contract_class(input, options) click to toggle source
# File lib/pragma/macro/classes.rb, line 91
def expected_contract_class(input, options)
  parts = input.class.name.split('::')

  [
    resource_namespace(input, options),
    'Contract',
    parts[(parts.index('Operation') + 1)..-1]
  ].join('::')
end
expected_instance_decorator_class(input, options) click to toggle source
# File lib/pragma/macro/classes.rb, line 75
def expected_instance_decorator_class(input, options)
  [
    resource_namespace(input, options),
    'Decorator',
    'Instance'
  ].join('::')
end
expected_model_class(input, options) click to toggle source
# File lib/pragma/macro/classes.rb, line 57
def expected_model_class(input, options)
  [
    root_namespace(input, options).join('::'),
    resource_namespace(input, options).last
  ].join('::')
end
expected_policy_class(input, options) click to toggle source
# File lib/pragma/macro/classes.rb, line 64
def expected_policy_class(input, options)
  [
    resource_namespace(input, options),
    'Policy'
  ].join('::')
end
expected_policy_scope_class(input, options) click to toggle source
# File lib/pragma/macro/classes.rb, line 71
def expected_policy_scope_class(input, options)
  "#{expected_policy_class(input, options)}::Scope"
end
resource_namespace(input, _options) click to toggle source
# File lib/pragma/macro/classes.rb, line 44
def resource_namespace(input, _options)
  parts = input.class.name.split('::')
  parts[0..(parts.index('Operation') - 1)]
end
root_namespace(input, options) click to toggle source
# File lib/pragma/macro/classes.rb, line 49
def root_namespace(input, options)
  resource_namespace = resource_namespace(input, options)
  return [] if resource_namespace.first.casecmp('API').zero?

  api_index = (resource_namespace.map(&:upcase).index('API') || 1)
  resource_namespace[0..(api_index - 1)]
end