Skip to content

Commit

Permalink
#270 Result method_missing
Browse files Browse the repository at this point in the history
OpenStruct does not actually return true for respond_to when passing in a variable writer method so delegate_missing_to fails in this regard
  • Loading branch information
aaronmallen committed Oct 27, 2020
1 parent 6c3b1c7 commit 6245c73
Show file tree
Hide file tree
Showing 2 changed files with 47 additions and 3 deletions.
20 changes: 17 additions & 3 deletions lib/active_interactor/interactor/result.rb
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
# frozen_string_literal: true

require 'active_support/core_ext/module/delegation'

module ActiveInteractor
module Interactor
# An Interactor Result object.
Expand Down Expand Up @@ -41,7 +39,6 @@ class Result
# @!method successful?
# @see ActiveInteractor::Interactor::State#success?
delegate :called, :called!, :fail?, :failure?, :success?, :successful?, to: :state
delegate_missing_to :context

# Initializes a new instance of {Result}
#
Expand Down Expand Up @@ -104,12 +101,29 @@ def handle_listed_errors(errors)
errors.each { |error| handle_errors(error) }
end

def method_missing(method_name, *args, &block)
context.public_send(method_name, *args, &block)
ActiveInteractor::Deprecation::V2.deprecation_warning(
method_name,
'calling #context methods on an ActiveInteractor::Interactor::Result is deprecated use #context instead',
caller
)
rescue NoMethodError
super
end

def resolve_errors!
all_errors = context.errors.uniq.compact
context.errors.clear
all_errors.each { |error| context.errors.add(error[0], error[1]) }
end

def respond_to_missing?(method_name, include_private = false)
return true if method_name[/.*(?==\z)/m]

context.respond_to?(method_name, include_private) || super
end

def rollback_called!
state.called.reverse_each do |interactor|
next if state.rolled_back.include? interactor
Expand Down
30 changes: 30 additions & 0 deletions spec/active_interactor/interactor/result_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -117,4 +117,34 @@
end
end
end

describe 'calling context methods' do
subject(:context_method) { result.bar = 'bar' }

before do
allow(ActiveInteractor::Deprecation::V2).to receive(:deprecation_warning).and_return(true)
end

let(:result) { described_class.new(context_object) }
let(:context_object) { build_context.new }

it { expect { context_method }.not_to raise_error }

it 'is expected to call the approriate context method' do
context_method

expect(context_object.bar).to eq 'bar'
end

it 'is expected to warn about deprecation' do
context_method

expect(ActiveInteractor::Deprecation::V2).to have_received(:deprecation_warning)
.with(
:bar=,
'calling #context methods on an ActiveInteractor::Interactor::Result is deprecated use #context instead',
any_args
)
end
end
end

0 comments on commit 6245c73

Please sign in to comment.