Skip to content

Commit

Permalink
fix call missing dependency
Browse files Browse the repository at this point in the history
  • Loading branch information
xronos-i-am committed Jan 29, 2025
1 parent d5d0bf4 commit 2e60acb
Show file tree
Hide file tree
Showing 3 changed files with 81 additions and 22 deletions.
1 change: 1 addition & 0 deletions lib/active_dry_deps.rb
Original file line number Diff line number Diff line change
Expand Up @@ -12,5 +12,6 @@ module ActiveDryDeps

class Error < StandardError; end
class DependencyNameInvalid < Error; end
class DependencyNotRegistered < Error; end

end
58 changes: 45 additions & 13 deletions lib/active_dry_deps/dependency.rb
Original file line number Diff line number Diff line change
Expand Up @@ -13,22 +13,34 @@ def initialize(resolver, receiver_method_alias: nil)
def receiver_method_string
Kernel.sprintf(
METHOD_TEMPLATES.fetch(container: true, method_call: !@method_name.nil?),
receiver_method_name: @receiver_method_name,
container_key_or_const_name: @const_name || @container_key,
method_name: @method_name,
receiver_method_name: @receiver_method_name,
container_key: @container_key || @const_name, # @const_name fallback for stub constant in test
const_name: @const_name || dependency_not_registered_error_string,
method_name: @method_name,
)
end
else
def receiver_method_string
Kernel.sprintf(
METHOD_TEMPLATES.fetch(container: !@container_key.nil?, method_call: !@method_name.nil?),
receiver_method_name: @receiver_method_name,
container_key_or_const_name: @const_name || @container_key,
method_name: @method_name,
receiver_method_name: @receiver_method_name,
container_key: @container_key,
const_name: @const_name || dependency_not_registered_error_string,
method_name: @method_name,
)
end
end

private def dependency_not_registered_error_string
dependency_name = @container_key || @const_name
<<~RUBY
raise(::ActiveDryDeps::DependencyNotRegistered, <<~TEXT)
Dependency +#{dependency_name}+ not registered.
Register it with `ActiveDryDeps::Deps.register('#{dependency_name}', ...)`
TEXT
RUBY
end

VALID_CONST_NAME = /^[[:upper:]][[[:alnum:]]:_]*$/
VALID_METHOD_NAME = /^[[[:alnum:]]_]+$/
LOWER = /[[:lower:]]/
Expand Down Expand Up @@ -79,21 +91,41 @@ def receiver_method_string

METHOD_TEMPLATES = {
{ container: true, method_call: true } => <<~RUBY,
# def CreateOrder(...)
# ::ActiveDryDeps::Deps::CONTAINER.resolve("OrderService::Create").call(...)
# def CreateOrder
# dependency_const =
# if ::ActiveDryDeps::Deps::CONTAINER.key?("OrderService::Create")
# ::ActiveDryDeps::Deps::CONTAINER.resolve("OrderService::Create")
# else
# OrderService::Create
# end
# dependency_const.call(...)
# end
def %<receiver_method_name>s(...)
(::ActiveDryDeps::Deps::CONTAINER.resolve_internal("%<container_key_or_const_name>s") || %<container_key_or_const_name>s).%<method_name>s(...)
dependency_const =
if ::ActiveDryDeps::Deps::CONTAINER.key?("%<container_key>s")
::ActiveDryDeps::Deps::CONTAINER.resolve_internal("%<container_key>s")
else
%<const_name>s
end
dependency_const.%<method_name>s(...)
end
RUBY
{ container: true, method_call: false } => <<~RUBY,
# def CreateOrder
# ::ActiveDryDeps::Deps::CONTAINER.resolve("OrderService::Create")
# if ::ActiveDryDeps::Deps::CONTAINER.key?("OrderService::Create")
# ::ActiveDryDeps::Deps::CONTAINER.resolve("OrderService::Create")
# else
# OrderService::Create
# end
# end
def %<receiver_method_name>s
::ActiveDryDeps::Deps::CONTAINER.resolve_internal("%<container_key_or_const_name>s") || %<container_key_or_const_name>s
if ::ActiveDryDeps::Deps::CONTAINER.key?("%<container_key>s")
::ActiveDryDeps::Deps::CONTAINER.resolve_internal("%<container_key>s")
else
%<const_name>s
end
end
RUBY
{ container: false, method_call: true } => <<~RUBY,
Expand All @@ -102,7 +134,7 @@ def %<receiver_method_name>s
# end
def %<receiver_method_name>s(...)
%<container_key_or_const_name>s.%<method_name>s(...)
%<const_name>s.%<method_name>s(...)
end
RUBY
{ container: false, method_call: false } => <<~RUBY,
Expand All @@ -111,7 +143,7 @@ def %<receiver_method_name>s(...)
# end
def %<receiver_method_name>s
%<container_key_or_const_name>s
%<const_name>s
end
RUBY
}.freeze
Expand Down
44 changes: 35 additions & 9 deletions spec/active_dry_deps_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,29 @@
}.to raise_error(ActiveDryDeps::DependencyNameInvalid, 'name +!invalid_identifier+ is not a valid Ruby identifier')
end

context 'when dependency missing' do
it 'fails when const not defined' do
expect {
service = Class.new { include Deps['UndefinedConst'] }
service.new.UndefinedConst()
}.to raise_error(NameError, /uninitialized constant.*UndefinedConst/)
end

it 'fails when dependency not registered' do
expect {
service = Class.new { include Deps['unknown_method'] }
service.new.unknown_method
}.to raise_error(::ActiveDryDeps::DependencyNotRegistered, /.+unknown_method.+not registered/)
end

it 'fails when method not defined' do
expect {
service = Class.new { include Deps['CreateOrder.unknown_method'] }
service.new.unknown_method
}.to raise_error(NoMethodError, /undefined method `unknown_method' for CreateOrder/)
end
end

describe '#register' do
it 'checks the container key' do
expect {
Expand All @@ -50,18 +73,25 @@
end

describe '#stub' do
def expect_call_orig
expect(CreateOrder.call).to eq %w[CreateDeparture CreateDeparture job-performed message-ok email-sent-hello track]
end

it 'stubs dependency at the container level' do
Deps.stub('CreateDeparture', double(call: '1'))

expect(CreateOrder.call).to eq %w[1 1 job-performed message-ok email-sent-hello track]
end

it 'unstub dependency' do
Deps.stub('CreateDeparture', double(call: '1'))
Deps.unstub

expect_call_orig
expect(CreateOrder.call).to eq %w[CreateDeparture CreateDeparture job-performed message-ok email-sent-hello track]
end

it 'stubs dependency with nil' do
Deps.stub('tick', nil)

service = CreateOrder.new

expect(service.tick).to eq nil
end

it 'raises exception when calls a stub block' do
Expand All @@ -71,10 +101,6 @@ def expect_call_orig

expect { CreateOrder.call }
.to raise_error(StandardError, 'Something went wrong')

Deps.unstub

expect_call_orig
end
end
end

0 comments on commit 2e60acb

Please sign in to comment.