Load base request class as needed

This commit is contained in:
Mark Maglana
2013-09-18 00:55:24 -07:00
parent e456788c36
commit 23a3862fca
2 changed files with 72 additions and 28 deletions

View File

@@ -1,12 +1,10 @@
module Aviator
class BaseRequestNotFoundError < StandardError
attr_reader :base_request_hierarchy,
:original_error
attr_reader :base_request_hierarchy
def initialize(base_hierarchy, original_error)
def initialize(base_hierarchy)
@base_request_hierarchy = base_hierarchy
@original_error = original_error
super("#{ base_request_hierarchy } could not be found!")
end
end
@@ -24,39 +22,66 @@ module Aviator
end
class << self
class RequestBuilder
def define_request(request_name, base_hierarchy=[:request], &block)
base_klass = base_hierarchy.inject(self) do |namespace, sym|
begin
class << self
def define_request(root_namespace, request_name, base_hierarchy=[:request], &block)
base_klass = get_request_class(root_namespace, base_hierarchy)
klass = Class.new(base_klass, &block)
namespace_arr = [
klass.provider,
klass.service,
klass.api_version,
klass.endpoint_type
]
namespace = namespace_arr.inject(root_namespace) do |namespace, sym|
const_name = sym.to_s.camelize
namespace.const_set(const_name, Module.new) unless namespace.const_defined?(const_name, false)
namespace.const_get(const_name, false)
end
klassname = request_name.to_s.camelize
if namespace.const_defined?(klassname, false)
raise RequestAlreadyDefinedError.new(namespace, klassname)
end
namespace.const_set(klassname, klass)
end
def get_request_class(root_namespace, request_class_arr)
request_class_arr.inject(root_namespace) do |namespace, sym|
namespace.const_get(sym.to_s.camelize, false)
rescue NameError => original_error
raise BaseRequestNotFoundError.new(base_hierarchy, original_error)
end
rescue NameError => e
arr = ['..', '..'] + request_class_arr
arr[-1,1] = arr.last.to_s + '.rb'
path = Pathname.new(__FILE__).join(*arr.map{|i| i.to_s }).expand_path
if path.exist?
require path
request_class_arr.inject(root_namespace) do |namespace, sym|
namespace.const_get(sym.to_s.camelize, false)
end
else
raise BaseRequestNotFoundError.new(request_class_arr)
end
end
klass = Class.new(base_klass, &block)
end
namespace_arr = [
klass.provider,
klass.service,
klass.api_version,
klass.endpoint_type
]
end
namespace = namespace_arr.inject(self) do |namespace, sym|
const_name = sym.to_s.camelize
namespace.const_set(const_name, Module.new) unless namespace.const_defined?(const_name, false)
namespace.const_get(const_name, false)
end
klassname = request_name.to_s.camelize
class << self
if namespace.const_defined?(klassname, false)
raise RequestAlreadyDefinedError.new(namespace, klassname)
end
namespace.const_set(klassname, klass)
def define_request(request_name, base_hierarchy=[:request], &block)
RequestBuilder.define_request self, request_name, base_hierarchy, &block
end
end # class << self

View File

@@ -156,6 +156,25 @@ class Aviator::Test
error.request_name.must_equal request[:name].to_s.camelize
end
it 'automatically attempts to load the base class if it\'s not yet loaded' do
base_arr = [:openstack, :identity, :v2, :public, :root]
child_arr = base_arr.first(base_arr.length - 1) + [:child]
builder.define_request child_arr.last, base_arr do; end
base_klass = base_arr.inject(builder) do |namespace, sym|
namespace.const_get(sym.to_s.camelize, false)
end
child_klass = child_arr.inject(builder) do |namespace, sym|
namespace.const_get(sym.to_s.camelize, false)
end
base_klass.wont_be_nil
child_klass.wont_be_nil
end
end
end