Skip to content

Commit

Permalink
Fix warning when overriding an exsiting method
Browse files Browse the repository at this point in the history
  • Loading branch information
pirj committed Mar 15, 2016
1 parent 24b1ad9 commit d485306
Show file tree
Hide file tree
Showing 3 changed files with 66 additions and 21 deletions.
2 changes: 1 addition & 1 deletion README.md
Expand Up @@ -404,7 +404,7 @@ simple.aasm(:work).current

_AASM_ doesn't prohibit to define the same event in more than one state machine. The
latest definition "wins" and overrides previous definitions. Nonetheless, a warning is issued:
`SimpleMultipleExample: The aasm event name run is already used!`.
`SimpleMultipleExample: overriding method 'run'!`.

All _AASM_ class- and instance-level `aasm` methods accept a state machine selector.
So, for example, to use inspection on a class level, you have to use
Expand Down
42 changes: 22 additions & 20 deletions lib/aasm/base.rb
Expand Up @@ -74,13 +74,10 @@ def initial_state(new_initial_state=nil)
def state(name, options={})
@state_machine.add_state(name, klass, options)

if klass.instance_methods.include?("#{name}?")
warn "#{klass.name}: The aasm state name #{name} is already used!"
end

aasm_name = @name
klass.send :define_method, "#{name}?", ->() do
aasm(:"#{aasm_name}").current_state == :"#{name}"
aasm_name = @name.to_sym
state = name.to_sym
safely_define_method klass, "#{name}?", -> do
aasm(aasm_name).current_state == state
end

unless klass.const_defined?("STATE_#{name.upcase}")
Expand All @@ -92,27 +89,24 @@ def state(name, options={})
def event(name, options={}, &block)
@state_machine.add_event(name, options, &block)

if klass.instance_methods.include?("may_#{name}?".to_sym)
warn "#{klass.name}: The aasm event name #{name} is already used!"
end
aasm_name = @name.to_sym
event = name.to_sym

# an addition over standard aasm so that, before firing an event, you can ask
# may_event? and get back a boolean that tells you whether the guard method
# on the transition will let this happen.
aasm_name = @name

klass.send :define_method, "may_#{name}?", ->(*args) do
aasm(:"#{aasm_name}").may_fire_event?(:"#{name}", *args)
safely_define_method klass, "may_#{name}?", ->(*args) do
aasm(aasm_name).may_fire_event?(event, *args)
end

klass.send :define_method, "#{name}!", ->(*args, &block) do
aasm(:"#{aasm_name}").current_event = :"#{name}!"
aasm_fire_event(:"#{aasm_name}", :"#{name}", {:persist => true}, *args, &block)
safely_define_method klass, "#{name}!", ->(*args, &block) do
aasm(aasm_name).current_event = :"#{name}!"
aasm_fire_event(aasm_name, event, {:persist => true}, *args, &block)
end

klass.send :define_method, "#{name}", ->(*args, &block) do
aasm(:"#{aasm_name}").current_event = :"#{name}"
aasm_fire_event(:"#{aasm_name}", :"#{name}", {:persist => false}, *args, &block)
safely_define_method klass, name, ->(*args, &block) do
aasm(aasm_name).current_event = event
aasm_fire_event(aasm_name, event, {:persist => false}, *args, &block)
end
end

Expand Down Expand Up @@ -183,5 +177,13 @@ def configure(key, default_value)
end
end

def safely_define_method(klass, method_name, method_definition)
if klass.instance_methods.include?(method_name.to_sym)
warn "#{klass.name}: overriding method '#{method_name}'!"
end

klass.send(:define_method, method_name, method_definition)
end

end
end
43 changes: 43 additions & 0 deletions spec/unit/override_warning_spec.rb
@@ -0,0 +1,43 @@
require 'spec_helper'

describe 'warns when overrides a method' do
module Clumsy
def self.included base
base.send :include, AASM

base.aasm do
state :valid
event(:save) { }
end
end
end

describe 'state' do
class Base
def valid?; end
end
it do
expect { Base.send :include, Clumsy }.
to output(/Base: overriding method 'valid\?'!/).to_stderr
end
end

describe 'event' do
context 'may?' do
class Base
def may_save?; end
def save!; end
def save; end
end
let(:klass) { Base }
it do
expect { Base.send :include, Clumsy }.
to output(/Base: overriding method 'may_save\?'!/).to_stderr
expect { Base.send :include, Clumsy }.
to output(/Base: overriding method 'save!'!/).to_stderr
expect { Base.send :include, Clumsy }.
to output(/Base: overriding method 'save'!/).to_stderr
end
end
end
end

0 comments on commit d485306

Please sign in to comment.