mirror of
https://github.com/aasm/aasm
synced 2023-03-27 23:22:41 -04:00
Merge branch 'master' into aasm4
Conflicts: CHANGELOG.md lib/aasm/event.rb
This commit is contained in:
commit
8bb01faebd
27 changed files with 215 additions and 302 deletions
|
@ -9,6 +9,10 @@
|
|||
[#80](https://github.com/aasm/aasm/issues/80)
|
||||
thanks to [@ejlangev](https://github.com/ejlangev))
|
||||
|
||||
## 3.1.0 (not yet released)
|
||||
|
||||
* deprecated old aasm_* class methods (old-style DSL), in preparation for AASM v4.0.0
|
||||
|
||||
## 3.0.24
|
||||
|
||||
* added support for event blocks (thanks to [@Intrepidd](https://github.com/Intrepidd))
|
||||
|
|
2
LICENSE
2
LICENSE
|
@ -1,4 +1,4 @@
|
|||
Copyright (c) 2006-2012 Scott Barron
|
||||
Copyright (c) 2006-2014 Scott Barron
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining
|
||||
a copy of this software and associated documentation files (the
|
||||
|
|
17
README.md
17
README.md
|
@ -257,6 +257,7 @@ to include Mongoid::Document before you include AASM.
|
|||
class Job
|
||||
include Mongoid::Document
|
||||
include AASM
|
||||
field :aasm_state
|
||||
aasm do
|
||||
...
|
||||
end
|
||||
|
@ -325,9 +326,9 @@ class Job < ActiveRecord::Base
|
|||
|
||||
aasm do
|
||||
state :sleeping, :initial => true
|
||||
state :running
|
||||
state :running, :after_commit => :notify_about_running_job
|
||||
|
||||
event :run, :after_commit => :notify_about_running_job do
|
||||
event :run do
|
||||
transitions :from => :sleeping, :to => :running
|
||||
end
|
||||
end
|
||||
|
@ -417,7 +418,7 @@ gem 'aasm'
|
|||
|
||||
## Latest changes ##
|
||||
|
||||
Look at the [CHANGELOG](https://github.com/aasm/aasm/blob/master/CHANGELOG.md) for details.
|
||||
Take a look at the [CHANGELOG](https://github.com/aasm/aasm/blob/master/CHANGELOG.md) for details about recent changes to the current version.
|
||||
|
||||
## Questions? ##
|
||||
|
||||
|
@ -427,11 +428,11 @@ Feel free to
|
|||
* [ask a question on StackOverflow](http://stackoverflow.com) (tag with `aasm`)
|
||||
* send us a tweet [@aasm](http://twitter.com/aasm)
|
||||
|
||||
## Authors ##
|
||||
## Maintainers ##
|
||||
|
||||
* [Scott Barron](https://github.com/rubyist)
|
||||
* [Travis Tilley](https://github.com/ttilley)
|
||||
* [Thorsten Böttger](http://github.com/alto)
|
||||
* [Scott Barron](https://github.com/rubyist) (2006–2009, original author)
|
||||
* [Travis Tilley](https://github.com/ttilley) (2009–2011)
|
||||
* [Thorsten Böttger](http://github.com/alto) (since 2011)
|
||||
|
||||
|
||||
## Warranty ##
|
||||
|
@ -443,7 +444,7 @@ purpose.
|
|||
|
||||
## License ##
|
||||
|
||||
Copyright (c) 2006-2012 Scott Barron
|
||||
Copyright (c) 2006-2014 Scott Barron
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining
|
||||
a copy of this software and associated documentation files (the
|
||||
|
|
|
@ -13,6 +13,3 @@ require 'ostruct'
|
|||
persistence
|
||||
aasm
|
||||
).each { |file| require File.join(File.dirname(__FILE__), 'aasm', file) }
|
||||
|
||||
# load the deprecated methods and modules
|
||||
Dir[File.join(File.dirname(__FILE__), 'aasm', 'deprecated', '*.rb')].sort.each { |f| require File.expand_path(f) }
|
||||
|
|
|
@ -26,52 +26,56 @@ module AASM
|
|||
@aasm
|
||||
end
|
||||
|
||||
# TODO: maybe better: aasm.initial_state
|
||||
# TODO remove this method in v4.0.0
|
||||
def aasm_initial_state(set_state=nil)
|
||||
if set_state
|
||||
# deprecated way to set the value
|
||||
warn ".aasm_initial_state(:name) is deprecated and will be removed in version 4.0.0; please use .aasm.initial_state = :name instead!"
|
||||
AASM::StateMachine[self].initial_state = set_state
|
||||
else
|
||||
warn ".aasm_initial_state is deprecated and will be removed in version 4.0.0; please use .aasm.initial_state instead!"
|
||||
AASM::StateMachine[self].initial_state
|
||||
end
|
||||
end
|
||||
|
||||
# is this better?: aasm.states.name.from_states
|
||||
# TODO remove this method in v4.0.0
|
||||
def aasm_from_states_for_state(state, options={})
|
||||
if options[:transition]
|
||||
aasm.events[options[:transition]].transitions_to_state(state).flatten.map(&:from).flatten
|
||||
else
|
||||
aasm.events.map {|k,v| v.transitions_to_state(state)}.flatten.map(&:from).flatten
|
||||
end
|
||||
warn ".aasm_from_states_for_state is deprecated and will be removed in version 4.0.0; please use .aasm.from_states_for_state instead!"
|
||||
aasm.from_states_for_state(state, options)
|
||||
end
|
||||
|
||||
# deprecated
|
||||
# TODO remove this method in v4.0.0
|
||||
def aasm_initial_state=(state)
|
||||
warn ".aasm_initial_state= is deprecated and will be removed in version 4.0.0"
|
||||
AASM::StateMachine[self].initial_state = state
|
||||
end
|
||||
|
||||
# deprecated
|
||||
# TODO remove this method in v4.0.0
|
||||
def aasm_state(name, options={})
|
||||
warn ".aasm_state is deprecated and will be removed in version 4.0.0; please use .aasm.state instead!"
|
||||
aasm.state(name, options)
|
||||
end
|
||||
|
||||
# deprecated
|
||||
# TODO remove this method in v4.0.0
|
||||
def aasm_event(name, options = {}, &block)
|
||||
warn ".aasm_event is deprecated and will be removed in version 4.0.0; please use .aasm.event instead!"
|
||||
aasm.event(name, options, &block)
|
||||
end
|
||||
|
||||
# deprecated
|
||||
# TODO remove this method in v4.0.0
|
||||
def aasm_states
|
||||
warn ".aasm_states is deprecated and will be removed in version 4.0.0; please use .aasm.states instead!"
|
||||
aasm.states
|
||||
end
|
||||
|
||||
# deprecated
|
||||
# TODO remove this method in v4.0.0
|
||||
def aasm_events
|
||||
warn ".aasm_events is deprecated and will be removed in version 4.0.0; please use .aasm.events instead!"
|
||||
aasm.events
|
||||
end
|
||||
|
||||
# deprecated
|
||||
# TODO remove this method in v4.0.0
|
||||
def aasm_states_for_select
|
||||
warn ".aasm_states_for_select is deprecated and will be removed in version 4.0.0; please use .aasm.states_for_select instead!"
|
||||
aasm.states_for_select
|
||||
end
|
||||
|
||||
|
@ -103,39 +107,39 @@ module AASM
|
|||
true
|
||||
end
|
||||
|
||||
# deprecated
|
||||
# TODO remove this method in v4.0.0
|
||||
def aasm_current_state
|
||||
# warn "#aasm_current_state is deprecated and will be removed in version 3.2.0; please use #aasm.state instead!"
|
||||
warn "#aasm_current_state is deprecated and will be removed in version 4.0.0; please use #aasm.current_state instead!"
|
||||
aasm.current_state
|
||||
end
|
||||
|
||||
# deprecated
|
||||
# TODO remove this method in v4.0.0
|
||||
def aasm_enter_initial_state
|
||||
# warn "#aasm_enter_initial_state is deprecated and will be removed in version 3.2.0; please use #aasm.enter_initial_state instead!"
|
||||
warn "#aasm_enter_initial_state is deprecated and will be removed in version 4.0.0; please use #aasm.enter_initial_state instead!"
|
||||
aasm.enter_initial_state
|
||||
end
|
||||
|
||||
# deprecated
|
||||
# TODO remove this method in v4.0.0
|
||||
def aasm_events_for_current_state
|
||||
# warn "#aasm_events_for_current_state is deprecated and will be removed in version 3.2.0; please use #aasm.events instead!"
|
||||
warn "#aasm_events_for_current_state is deprecated and will be removed in version 4.0.0; please use #aasm.events(aasm.current_state) instead!"
|
||||
aasm.events(aasm.current_state)
|
||||
end
|
||||
|
||||
# deprecated
|
||||
# TODO remove this method in v4.0.0
|
||||
def aasm_permissible_events_for_current_state
|
||||
# warn "#aasm_permissible_events_for_current_state is deprecated and will be removed in version 3.2.0; please use #aasm.permissible_events instead!"
|
||||
warn "#aasm_permissible_events_for_current_state is deprecated and will be removed in version 4.0.0; please use #aasm.permissible_events instead!"
|
||||
aasm.permissible_events
|
||||
end
|
||||
|
||||
# deprecated
|
||||
# TODO remove this method in v4.0.0
|
||||
def aasm_events_for_state(state_name)
|
||||
# warn "#aasm_events_for_state(state_name) is deprecated and will be removed in version 3.2.0; please use #aasm.events(state_name) instead!"
|
||||
warn "#aasm_events_for_state(state_name) is deprecated and will be removed in version 4.0.0; please use #aasm.events(state_name) instead!"
|
||||
aasm.events(state_name)
|
||||
end
|
||||
|
||||
# deprecated
|
||||
# TODO remove this method in v4.0.0
|
||||
def aasm_human_state
|
||||
# warn "#aasm_human_state is deprecated and will be removed in version 3.2.0; please use #aasm.human_state instead!"
|
||||
warn "#aasm_human_state is deprecated and will be removed in version 4.0.0; please use #aasm.human_state instead!"
|
||||
aasm.human_state
|
||||
end
|
||||
|
||||
|
@ -156,7 +160,7 @@ private
|
|||
end
|
||||
|
||||
def aasm_fire_event(event_name, options, *args, &block)
|
||||
event = self.class.aasm_events[event_name]
|
||||
event = self.class.aasm.events[event_name]
|
||||
begin
|
||||
old_state = aasm.state_object_for_name(aasm.current_state)
|
||||
old_state.fire_callbacks(:exit, self)
|
||||
|
|
|
@ -25,13 +25,16 @@ module AASM
|
|||
end
|
||||
end
|
||||
|
||||
def initial_state
|
||||
@state_machine.initial_state
|
||||
def initial_state(new_initial_state=nil)
|
||||
if new_initial_state
|
||||
@state_machine.initial_state = new_initial_state
|
||||
else
|
||||
@state_machine.initial_state
|
||||
end
|
||||
end
|
||||
|
||||
# define a state
|
||||
def state(name, options={})
|
||||
# @clazz.aasm_state(name, options)
|
||||
@state_machine.add_state(name, @clazz, options)
|
||||
@state_machine.initial_state = name if options[:initial] || !@state_machine.initial_state
|
||||
|
||||
|
@ -46,8 +49,6 @@ module AASM
|
|||
|
||||
# define an event
|
||||
def event(name, options={}, &block)
|
||||
# @clazz.aasm_event(name, options, &block)
|
||||
|
||||
@state_machine.events[name] = AASM::Event.new(name, options, &block)
|
||||
|
||||
# an addition over standard aasm so that, before firing an event, you can ask
|
||||
|
@ -78,5 +79,13 @@ module AASM
|
|||
states.map { |state| state.for_select }
|
||||
end
|
||||
|
||||
def from_states_for_state(state, options={})
|
||||
if options[:transition]
|
||||
events[options[:transition]].transitions_to_state(state).flatten.map(&:from).flatten
|
||||
else
|
||||
events.map {|k,v| v.transitions_to_state(state)}.flatten.map(&:from).flatten
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,15 +0,0 @@
|
|||
module AASM
|
||||
|
||||
module ClassMethods
|
||||
def human_event_name(*args)
|
||||
warn "AASM.human_event_name is deprecated and will be removed in version 3.1.0; please use AASM.aasm_human_event_name instead!"
|
||||
aasm_human_event_name(*args)
|
||||
end
|
||||
end
|
||||
|
||||
def human_state
|
||||
warn "AASM#human_state is deprecated and will be removed in version 3.1.0; please use AASM#aasm_human_state instead!"
|
||||
aasm_human_state
|
||||
end
|
||||
|
||||
end
|
|
@ -36,9 +36,9 @@ module AASM
|
|||
@transitions.select { |t| t.to == state }
|
||||
end
|
||||
|
||||
# deprecated
|
||||
# TODO remove this method in v4.0.0
|
||||
def all_transitions
|
||||
# warn "Event#all_transitions is deprecated and will be removed in version 3.2.0; please use Event#transitions instead!"
|
||||
warn "Event#all_transitions is deprecated and will be removed in version 4.0.0; please use Event#transitions instead!"
|
||||
transitions
|
||||
end
|
||||
|
||||
|
@ -56,6 +56,19 @@ module AASM
|
|||
end
|
||||
end
|
||||
|
||||
## DSL interface
|
||||
def transitions(definitions=nil)
|
||||
if definitions # define new transitions
|
||||
# Create a separate transition for each from state to the given state
|
||||
Array(definitions[:from]).each do |s|
|
||||
@transitions << AASM::Transition.new(definitions.merge({:from => s.to_sym}))
|
||||
end
|
||||
# Create a transition if to is specified without from (transitions from ANY state)
|
||||
@transitions << AASM::Transition.new(definitions) if @transitions.empty? && definitions[:to]
|
||||
end
|
||||
@transitions
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def update(options = {}, &block)
|
||||
|
@ -70,7 +83,7 @@ module AASM
|
|||
def _fire(obj, test, to_state=nil, *args)
|
||||
result = test ? false : nil
|
||||
if @transitions.map(&:from).any?
|
||||
transitions = transitions_from_state(obj.aasm_current_state)
|
||||
transitions = @transitions.select { |t| t.from == obj.aasm.current_state }
|
||||
return result if transitions.size == 0
|
||||
else
|
||||
transitions = @transitions
|
||||
|
@ -118,19 +131,6 @@ module AASM
|
|||
end
|
||||
end
|
||||
|
||||
## DSL interface
|
||||
def transitions(trans_opts=nil)
|
||||
if trans_opts # define new transitions
|
||||
# Create a separate transition for each from state to the given state
|
||||
Array(trans_opts[:from]).each do |s|
|
||||
@transitions << AASM::Transition.new(trans_opts.merge({:from => s.to_sym}))
|
||||
end
|
||||
# Create a transition if to is specified without from (transitions from ANY state)
|
||||
@transitions << AASM::Transition.new(trans_opts) if @transitions.empty? && trans_opts[:to]
|
||||
end
|
||||
@transitions
|
||||
end
|
||||
|
||||
[:after, :before, :error, :success].each do |callback_name|
|
||||
define_method callback_name do |*args, &block|
|
||||
options[callback_name] = Array(options[callback_name])
|
||||
|
|
|
@ -15,7 +15,7 @@ module AASM
|
|||
end
|
||||
|
||||
def enter_initial_state
|
||||
state_name = determine_state_name(@instance.class.aasm_initial_state)
|
||||
state_name = determine_state_name(@instance.class.aasm.initial_state)
|
||||
state_object = state_object_for_name(state_name)
|
||||
|
||||
state_object.fire_callbacks(:before_enter, @instance)
|
||||
|
|
|
@ -71,10 +71,10 @@ module AASM
|
|||
# Writes <tt>state</tt> to the state column and persists it to the database
|
||||
#
|
||||
# foo = Foo.find(1)
|
||||
# foo.aasm_current_state # => :opened
|
||||
# foo.aasm.current_state # => :opened
|
||||
# foo.close!
|
||||
# foo.aasm_current_state # => :closed
|
||||
# Foo.find(1).aasm_current_state # => :closed
|
||||
# foo.aasm.current_state # => :closed
|
||||
# Foo.find(1).aasm.current_state # => :closed
|
||||
#
|
||||
# NOTE: intended to be called from an event
|
||||
def aasm_write_state(state)
|
||||
|
@ -97,13 +97,13 @@ module AASM
|
|||
# Writes <tt>state</tt> to the state column, but does not persist it to the database
|
||||
#
|
||||
# foo = Foo.find(1)
|
||||
# foo.aasm_current_state # => :opened
|
||||
# foo.aasm.current_state # => :opened
|
||||
# foo.close
|
||||
# foo.aasm_current_state # => :closed
|
||||
# Foo.find(1).aasm_current_state # => :opened
|
||||
# foo.aasm.current_state # => :closed
|
||||
# Foo.find(1).aasm.current_state # => :opened
|
||||
# foo.save
|
||||
# foo.aasm_current_state # => :closed
|
||||
# Foo.find(1).aasm_current_state # => :closed
|
||||
# foo.aasm.current_state # => :closed
|
||||
# Foo.find(1).aasm.current_state # => :closed
|
||||
#
|
||||
# NOTE: intended to be called from an event
|
||||
def aasm_write_state_without_persistence(state)
|
||||
|
|
|
@ -35,7 +35,7 @@ module AASM
|
|||
def aasm_read_state
|
||||
state = send(self.class.aasm_column)
|
||||
if new_record?
|
||||
state.blank? ? aasm.determine_state_name(self.class.aasm_initial_state) : state.to_sym
|
||||
state.blank? ? aasm.determine_state_name(self.class.aasm.initial_state) : state.to_sym
|
||||
else
|
||||
state.nil? ? nil : state.to_sym
|
||||
end
|
||||
|
|
|
@ -66,10 +66,10 @@ module AASM
|
|||
# using update_attribute (which bypasses validation)
|
||||
#
|
||||
# foo = Foo.find(1)
|
||||
# foo.aasm_current_state # => :opened
|
||||
# foo.aasm.current_state # => :opened
|
||||
# foo.close!
|
||||
# foo.aasm_current_state # => :closed
|
||||
# Foo.find(1).aasm_current_state # => :closed
|
||||
# foo.aasm.current_state # => :closed
|
||||
# Foo.find(1).aasm.current_state # => :closed
|
||||
#
|
||||
# NOTE: intended to be called from an event
|
||||
def aasm_write_state(state)
|
||||
|
@ -87,13 +87,13 @@ module AASM
|
|||
# Writes <tt>state</tt> to the state column, but does not persist it to the database
|
||||
#
|
||||
# foo = Foo.find(1)
|
||||
# foo.aasm_current_state # => :opened
|
||||
# foo.aasm.current_state # => :opened
|
||||
# foo.close
|
||||
# foo.aasm_current_state # => :closed
|
||||
# Foo.find(1).aasm_current_state # => :opened
|
||||
# foo.aasm.current_state # => :closed
|
||||
# Foo.find(1).aasm.current_state # => :opened
|
||||
# foo.save
|
||||
# foo.aasm_current_state # => :closed
|
||||
# Foo.find(1).aasm_current_state # => :closed
|
||||
# foo.aasm.current_state # => :closed
|
||||
# Foo.find(1).aasm.current_state # => :closed
|
||||
#
|
||||
# NOTE: intended to be called from an event
|
||||
def aasm_write_state_without_persistence(state)
|
||||
|
|
|
@ -1,41 +0,0 @@
|
|||
class CallbackOldDsl
|
||||
include AASM
|
||||
|
||||
aasm_initial_state :open
|
||||
aasm_state :open,
|
||||
:before_enter => :before_enter_open,
|
||||
:after_enter => :after_enter_open,
|
||||
:before_exit => :before_exit_open,
|
||||
:exit => :exit_open,
|
||||
:after_exit => :after_exit_open
|
||||
aasm_state :closed,
|
||||
:before_enter => :before_enter_closed,
|
||||
:enter => :enter_closed,
|
||||
:after_enter => :after_enter_closed,
|
||||
:before_exit => :before_exit_closed,
|
||||
:after_exit => :after_exit_closed
|
||||
|
||||
aasm_event :close, :before => :before, :after => :after do
|
||||
transitions :to => :closed, :from => [:open]
|
||||
end
|
||||
|
||||
aasm_event :open, :before => :before, :after => :after do
|
||||
transitions :to => :open, :from => :closed
|
||||
end
|
||||
|
||||
def before_enter_open; end
|
||||
def before_exit_open; end
|
||||
def after_enter_open; end
|
||||
def after_exit_open; end
|
||||
|
||||
def before_enter_closed; end
|
||||
def before_exit_closed; end
|
||||
def after_enter_closed; end
|
||||
def after_exit_closed; end
|
||||
|
||||
def before; end
|
||||
def after; end
|
||||
|
||||
def enter_closed; end
|
||||
def exit_open; end
|
||||
end
|
|
@ -2,7 +2,7 @@ class NoScopeMongoid
|
|||
include Mongoid::Document
|
||||
include AASM
|
||||
|
||||
field :status, type: String
|
||||
field :status, :type => String
|
||||
|
||||
aasm :create_scopes => false, :column => :status do
|
||||
state :ignored_scope
|
||||
|
|
|
@ -2,9 +2,10 @@ class SimpleMongoid
|
|||
include Mongoid::Document
|
||||
include AASM
|
||||
|
||||
field :status, type: String
|
||||
field :status, :type => String
|
||||
|
||||
aasm_column :status
|
||||
aasm_state :unknown_scope
|
||||
aasm_state :new
|
||||
aasm column: :status do
|
||||
state :unknown_scope
|
||||
state :new
|
||||
end
|
||||
end
|
||||
|
|
|
@ -2,7 +2,7 @@ class SimpleNewDslMongoid
|
|||
include Mongoid::Document
|
||||
include AASM
|
||||
|
||||
field :status, type: String
|
||||
field :status, :type => String
|
||||
|
||||
aasm :column => :status
|
||||
aasm do
|
||||
|
|
|
@ -2,16 +2,18 @@ module Models
|
|||
class Process
|
||||
include AASM
|
||||
|
||||
aasm_state :sleeping
|
||||
aasm_state :running
|
||||
aasm_state :suspended
|
||||
aasm do
|
||||
state :sleeping
|
||||
state :running
|
||||
state :suspended
|
||||
|
||||
aasm_event :start do
|
||||
transitions :from => :sleeping, :to => :running
|
||||
end
|
||||
event :start do
|
||||
transitions :from => :sleeping, :to => :running
|
||||
end
|
||||
|
||||
aasm_event :stop do
|
||||
transitions :from => :running, :to => :suspended
|
||||
event :stop do
|
||||
transitions :from => :running, :to => :suspended
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
|
|
|
@ -36,13 +36,6 @@ class Transient < ActiveRecord::Base
|
|||
include AASM
|
||||
end
|
||||
|
||||
class Simple < ActiveRecord::Base
|
||||
include AASM
|
||||
aasm_column :status
|
||||
aasm_state :unknown_scope
|
||||
aasm_state :new
|
||||
end
|
||||
|
||||
class SimpleNewDsl < ActiveRecord::Base
|
||||
include AASM
|
||||
aasm :column => :status
|
||||
|
@ -59,9 +52,6 @@ class NoScope < ActiveRecord::Base
|
|||
end
|
||||
end
|
||||
|
||||
class Derivate < Simple
|
||||
end
|
||||
|
||||
class DerivateNewDsl < SimpleNewDsl
|
||||
end
|
||||
|
||||
|
@ -72,8 +62,10 @@ class Thief < ActiveRecord::Base
|
|||
set_table_name "thieves"
|
||||
end
|
||||
include AASM
|
||||
aasm_initial_state Proc.new { |thief| thief.skilled ? :rich : :jailed }
|
||||
aasm_state :rich
|
||||
aasm_state :jailed
|
||||
aasm do
|
||||
state :rich
|
||||
state :jailed
|
||||
initial_state Proc.new {|thief| thief.skilled ? :rich : :jailed }
|
||||
end
|
||||
attr_accessor :skilled, :aasm_state
|
||||
end
|
||||
|
|
|
@ -1,23 +1,5 @@
|
|||
require 'spec_helper'
|
||||
|
||||
describe 'callbacks for the old DSL' do
|
||||
let(:callback) {CallbackOldDsl.new}
|
||||
|
||||
it "should get close callbacks" do
|
||||
callback.should_receive(:exit_open).once.ordered
|
||||
callback.should_receive(:before).once.ordered
|
||||
callback.should_receive(:before_exit_open).once.ordered # these should be before the state changes
|
||||
callback.should_receive(:before_enter_closed).once.ordered
|
||||
callback.should_receive(:enter_closed).once.ordered
|
||||
callback.should_receive(:aasm_write_state).once.ordered.and_return(true) # this is when the state changes
|
||||
callback.should_receive(:after_exit_open).once.ordered # these should be after the state changes
|
||||
callback.should_receive(:after_enter_closed).once.ordered
|
||||
callback.should_receive(:after).once.ordered
|
||||
|
||||
callback.close!
|
||||
end
|
||||
end
|
||||
|
||||
describe 'callbacks for the new DSL' do
|
||||
let(:callback) {CallbackNewDsl.new}
|
||||
|
||||
|
@ -72,8 +54,10 @@ describe 'event callbacks' do
|
|||
describe "with an error callback defined" do
|
||||
before do
|
||||
class Foo
|
||||
aasm_event :safe_close, :success => :success_callback, :error => :error_callback do
|
||||
transitions :to => :closed, :from => [:open]
|
||||
aasm do
|
||||
event :safe_close, :success => :success_callback, :error => :error_callback do
|
||||
transitions :to => :closed, :from => [:open]
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
@ -4,7 +4,7 @@ describe 'on initialization' do
|
|||
let(:auth) {AuthMachine.new}
|
||||
|
||||
it 'should be in the pending state' do
|
||||
auth.aasm_current_state.should == :pending
|
||||
auth.aasm.current_state.should == :pending
|
||||
end
|
||||
|
||||
it 'should have an activation code' do
|
||||
|
@ -55,14 +55,14 @@ describe 'when being unsuspended' do
|
|||
auth.suspend!
|
||||
auth.unsuspend!
|
||||
|
||||
auth.aasm_current_state.should == :active
|
||||
auth.aasm.current_state.should == :active
|
||||
end
|
||||
|
||||
it 'should be pending if not previously activated, but an activation code is present' do
|
||||
auth.suspend!
|
||||
auth.unsuspend!
|
||||
|
||||
auth.aasm_current_state.should == :pending
|
||||
auth.aasm.current_state.should == :pending
|
||||
end
|
||||
|
||||
it 'should be passive if not previously activated and there is no activation code' do
|
||||
|
@ -70,6 +70,6 @@ describe 'when being unsuspended' do
|
|||
auth.suspend!
|
||||
auth.unsuspend!
|
||||
|
||||
auth.aasm_current_state.should == :passive
|
||||
auth.aasm.current_state.should == :passive
|
||||
end
|
||||
end
|
||||
|
|
|
@ -26,7 +26,7 @@ describe 'adding an event' do
|
|||
end
|
||||
|
||||
it 'should create transitions' do
|
||||
transitions = event.all_transitions
|
||||
transitions = event.transitions
|
||||
transitions[0].from.should == :open
|
||||
transitions[0].to.should == :closed
|
||||
transitions[1].from.should == :received
|
||||
|
@ -60,8 +60,7 @@ end
|
|||
|
||||
describe 'firing an event' do
|
||||
it 'should return nil if the transitions are empty' do
|
||||
obj = double('object')
|
||||
obj.stub(:aasm_current_state)
|
||||
obj = double('object', :aasm => double('aasm', :current_state => 'open'))
|
||||
|
||||
event = AASM::Event.new(:event)
|
||||
event.fire(obj).should be_nil
|
||||
|
@ -72,8 +71,7 @@ describe 'firing an event' do
|
|||
transitions :to => :closed, :from => [:open, :received]
|
||||
end
|
||||
|
||||
obj = double('object')
|
||||
obj.stub(:aasm_current_state).and_return(:open)
|
||||
obj = double('object', :aasm => double('aasm', :current_state => :open))
|
||||
|
||||
event.fire(obj).should == :closed
|
||||
end
|
||||
|
@ -83,8 +81,7 @@ describe 'firing an event' do
|
|||
transitions :to => :closed, :from => [:open, :received], :guard => :guard_fn
|
||||
end
|
||||
|
||||
obj = double('object')
|
||||
obj.stub(:aasm_current_state).and_return(:open)
|
||||
obj = double('object', :aasm => double('aasm', :current_state => :open))
|
||||
obj.should_receive(:guard_fn).with('arg1', 'arg2').and_return(true)
|
||||
|
||||
event.fire(obj, nil, 'arg1', 'arg2').should == :closed
|
||||
|
@ -96,8 +93,10 @@ describe 'should fire callbacks' do
|
|||
describe 'success' do
|
||||
it "if it's a symbol" do
|
||||
ThisNameBetterNotBeInUse.instance_eval {
|
||||
aasm_event :with_symbol, :success => :symbol_success_callback do
|
||||
transitions :to => :symbol, :from => [:initial]
|
||||
aasm do
|
||||
event :with_symbol, :success => :symbol_success_callback do
|
||||
transitions :to => :symbol, :from => [:initial]
|
||||
end
|
||||
end
|
||||
}
|
||||
|
||||
|
@ -108,8 +107,10 @@ describe 'should fire callbacks' do
|
|||
|
||||
it "if it's a string" do
|
||||
ThisNameBetterNotBeInUse.instance_eval {
|
||||
aasm_event :with_string, :success => 'string_success_callback' do
|
||||
transitions :to => :string, :from => [:initial]
|
||||
aasm do
|
||||
event :with_string, :success => 'string_success_callback' do
|
||||
transitions :to => :string, :from => [:initial]
|
||||
end
|
||||
end
|
||||
}
|
||||
|
||||
|
@ -120,8 +121,10 @@ describe 'should fire callbacks' do
|
|||
|
||||
it "if passed an array of strings and/or symbols" do
|
||||
ThisNameBetterNotBeInUse.instance_eval {
|
||||
aasm_event :with_array, :success => [:success_callback1, 'success_callback2'] do
|
||||
transitions :to => :array, :from => [:initial]
|
||||
aasm do
|
||||
event :with_array, :success => [:success_callback1, 'success_callback2'] do
|
||||
transitions :to => :array, :from => [:initial]
|
||||
end
|
||||
end
|
||||
}
|
||||
|
||||
|
@ -133,8 +136,10 @@ describe 'should fire callbacks' do
|
|||
|
||||
it "if passed an array of strings and/or symbols and/or procs" do
|
||||
ThisNameBetterNotBeInUse.instance_eval {
|
||||
aasm_event :with_array_including_procs, :success => [:success_callback1, 'success_callback2', lambda { proc_success_callback }] do
|
||||
transitions :to => :array, :from => [:initial]
|
||||
aasm do
|
||||
event :with_array_including_procs, :success => [:success_callback1, 'success_callback2', lambda { proc_success_callback }] do
|
||||
transitions :to => :array, :from => [:initial]
|
||||
end
|
||||
end
|
||||
}
|
||||
|
||||
|
@ -147,8 +152,10 @@ describe 'should fire callbacks' do
|
|||
|
||||
it "if it's a proc" do
|
||||
ThisNameBetterNotBeInUse.instance_eval {
|
||||
aasm_event :with_proc, :success => lambda { proc_success_callback } do
|
||||
transitions :to => :proc, :from => [:initial]
|
||||
aasm do
|
||||
event :with_proc, :success => lambda { proc_success_callback } do
|
||||
transitions :to => :proc, :from => [:initial]
|
||||
end
|
||||
end
|
||||
}
|
||||
|
||||
|
@ -161,14 +168,16 @@ describe 'should fire callbacks' do
|
|||
describe 'after' do
|
||||
it "if they set different ways" do
|
||||
ThisNameBetterNotBeInUse.instance_eval do
|
||||
aasm_event :with_afters, :after => :do_one_thing_after do
|
||||
after do
|
||||
do_another_thing_after_too
|
||||
aasm do
|
||||
event :with_afters, :after => :do_one_thing_after do
|
||||
after do
|
||||
do_another_thing_after_too
|
||||
end
|
||||
after do
|
||||
do_third_thing_at_last
|
||||
end
|
||||
transitions :to => :proc, :from => [:initial]
|
||||
end
|
||||
after do
|
||||
do_third_thing_at_last
|
||||
end
|
||||
transitions :to => :proc, :from => [:initial]
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -183,11 +192,13 @@ describe 'should fire callbacks' do
|
|||
describe 'before' do
|
||||
it "if it's a proc" do
|
||||
ThisNameBetterNotBeInUse.instance_eval do
|
||||
aasm_event :before_as_proc do
|
||||
before do
|
||||
do_something_before
|
||||
aasm do
|
||||
event :before_as_proc do
|
||||
before do
|
||||
do_something_before
|
||||
end
|
||||
transitions :to => :proc, :from => [:initial]
|
||||
end
|
||||
transitions :to => :proc, :from => [:initial]
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -199,11 +210,13 @@ describe 'should fire callbacks' do
|
|||
|
||||
it 'in right order' do
|
||||
ThisNameBetterNotBeInUse.instance_eval do
|
||||
aasm_event :in_right_order, :after => :do_something_after do
|
||||
before do
|
||||
do_something_before
|
||||
aasm do
|
||||
event :in_right_order, :after => :do_something_after do
|
||||
before do
|
||||
do_something_before
|
||||
end
|
||||
transitions :to => :proc, :from => [:initial]
|
||||
end
|
||||
transitions :to => :proc, :from => [:initial]
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -219,22 +232,22 @@ describe 'parametrised events' do
|
|||
|
||||
it 'should transition to specified next state (sleeping to showering)' do
|
||||
pe.wakeup!(:showering)
|
||||
pe.aasm_current_state.should == :showering
|
||||
pe.aasm.current_state.should == :showering
|
||||
end
|
||||
|
||||
it 'should transition to specified next state (sleeping to working)' do
|
||||
pe.wakeup!(:working)
|
||||
pe.aasm_current_state.should == :working
|
||||
pe.aasm.current_state.should == :working
|
||||
end
|
||||
|
||||
it 'should transition to default (first or showering) state' do
|
||||
pe.wakeup!
|
||||
pe.aasm_current_state.should == :showering
|
||||
pe.aasm.current_state.should == :showering
|
||||
end
|
||||
|
||||
it 'should transition to default state when on_transition invoked' do
|
||||
pe.dress!(nil, 'purple', 'dressy')
|
||||
pe.aasm_current_state.should == :working
|
||||
pe.aasm.current_state.should == :working
|
||||
end
|
||||
|
||||
it 'should call on_transition method with args' do
|
||||
|
|
|
@ -5,8 +5,8 @@ class Banker
|
|||
aasm do
|
||||
state :retired
|
||||
state :selling_bad_mortgages
|
||||
initial_state Proc.new { |banker| banker.rich? ? :retired : :selling_bad_mortgages }
|
||||
end
|
||||
aasm_initial_state Proc.new { |banker| banker.rich? ? :retired : :selling_bad_mortgages }
|
||||
RICH = 1_000_000
|
||||
attr_accessor :balance
|
||||
def initialize(balance = 0); self.balance = balance; end
|
||||
|
@ -17,12 +17,11 @@ describe 'initial states' do
|
|||
let(:bar) {Bar.new}
|
||||
|
||||
it 'should use the first state defined if no initial state is given' do
|
||||
bar.aasm_current_state.should == :read
|
||||
# bar.aasm.current_state.should == :read # not yet supported
|
||||
bar.aasm.current_state.should == :read
|
||||
end
|
||||
|
||||
it 'should determine initial state from the Proc results' do
|
||||
Banker.new(Banker::RICH - 1).aasm_current_state.should == :selling_bad_mortgages
|
||||
Banker.new(Banker::RICH + 1).aasm_current_state.should == :retired
|
||||
Banker.new(Banker::RICH - 1).aasm.current_state.should == :selling_bad_mortgages
|
||||
Banker.new(Banker::RICH + 1).aasm.current_state.should == :retired
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,19 +1,6 @@
|
|||
require 'spec_helper'
|
||||
|
||||
describe 'inspection for common cases' do
|
||||
it 'should support the old DSL' do
|
||||
Foo.should respond_to(:aasm_states)
|
||||
Foo.aasm_states.should include(:open)
|
||||
Foo.aasm_states.should include(:closed)
|
||||
|
||||
Foo.should respond_to(:aasm_initial_state)
|
||||
Foo.aasm_initial_state.should == :open
|
||||
|
||||
Foo.should respond_to(:aasm_events)
|
||||
Foo.aasm_events.should include(:close)
|
||||
Foo.aasm_events.should include(:null)
|
||||
end
|
||||
|
||||
it 'should support the new DSL' do
|
||||
Foo.aasm.should respond_to(:states)
|
||||
Foo.aasm.states.should include(:open)
|
||||
|
@ -74,35 +61,35 @@ end
|
|||
|
||||
describe "special cases" do
|
||||
it "should support valid a state name" do
|
||||
Argument.aasm_states.should include(:invalid)
|
||||
Argument.aasm_states.should include(:valid)
|
||||
Argument.aasm.states.should include(:invalid)
|
||||
Argument.aasm.states.should include(:valid)
|
||||
|
||||
argument = Argument.new
|
||||
argument.invalid?.should be_true
|
||||
argument.aasm_current_state.should == :invalid
|
||||
argument.aasm.current_state.should == :invalid
|
||||
|
||||
argument.valid!
|
||||
argument.valid?.should be_true
|
||||
argument.aasm_current_state.should == :valid
|
||||
argument.aasm.current_state.should == :valid
|
||||
end
|
||||
end
|
||||
|
||||
describe :aasm_states_for_select do
|
||||
describe 'aasm.states_for_select' do
|
||||
it "should return a select friendly array of states" do
|
||||
Foo.should respond_to(:aasm_states_for_select)
|
||||
Foo.aasm_states_for_select.should == [['Open', 'open'], ['Closed', 'closed']]
|
||||
Foo.aasm.should respond_to(:states_for_select)
|
||||
Foo.aasm.states_for_select.should == [['Open', 'open'], ['Closed', 'closed']]
|
||||
end
|
||||
end
|
||||
|
||||
describe :aasm_from_states_for_state do
|
||||
describe 'aasm.from_states_for_state' do
|
||||
it "should return all from states for a state" do
|
||||
AuthMachine.should respond_to(:aasm_from_states_for_state)
|
||||
froms = AuthMachine.aasm_from_states_for_state(:active)
|
||||
AuthMachine.aasm.should respond_to(:from_states_for_state)
|
||||
froms = AuthMachine.aasm.from_states_for_state(:active)
|
||||
[:pending, :passive, :suspended].each {|from| froms.should include(from)}
|
||||
end
|
||||
|
||||
it "should return from states for a state for a particular transition only" do
|
||||
froms = AuthMachine.aasm_from_states_for_state(:active, :transition => :unsuspend)
|
||||
froms = AuthMachine.aasm.from_states_for_state(:active, :transition => :unsuspend)
|
||||
[:suspended].each {|from| froms.should include(from)}
|
||||
end
|
||||
end
|
||||
|
|
|
@ -10,12 +10,12 @@ class LocalizerTestModel < ActiveRecord::Base
|
|||
|
||||
attr_accessor :aasm_state
|
||||
|
||||
aasm_initial_state :opened
|
||||
aasm_state :opened
|
||||
aasm_state :closed
|
||||
|
||||
aasm_event :close
|
||||
aasm_event :open
|
||||
aasm do
|
||||
state :opened, :initial => true
|
||||
state :closed
|
||||
event :close
|
||||
event :open
|
||||
end
|
||||
end
|
||||
|
||||
describe 'localized state names' do
|
||||
|
@ -52,13 +52,13 @@ describe AASM::Localizer, "new style" do
|
|||
let (:foo_opened) { LocalizerTestModel.new }
|
||||
let (:foo_closed) { LocalizerTestModel.new.tap { |x| x.aasm_state = :closed } }
|
||||
|
||||
context 'aasm_human_state' do
|
||||
context 'aasm.human_state' do
|
||||
it 'should return translated state value' do
|
||||
foo_opened.aasm_human_state.should == "It's open now!"
|
||||
foo_opened.aasm.human_state.should == "It's open now!"
|
||||
end
|
||||
|
||||
it 'should return humanized value if not localized' do
|
||||
foo_closed.aasm_human_state.should == "Closed"
|
||||
foo_closed.aasm.human_state.should == "Closed"
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -87,13 +87,13 @@ describe AASM::Localizer, "deprecated style" do
|
|||
let (:foo_opened) { LocalizerTestModel.new }
|
||||
let (:foo_closed) { LocalizerTestModel.new.tap { |x| x.aasm_state = :closed } }
|
||||
|
||||
context 'aasm_human_state' do
|
||||
context 'aasm.human_state' do
|
||||
it 'should return translated state value' do
|
||||
foo_opened.aasm_human_state.should == "It's open now!"
|
||||
foo_opened.aasm.human_state.should == "It's open now!"
|
||||
end
|
||||
|
||||
it 'should return humanized value if not localized' do
|
||||
foo_closed.aasm_human_state.should == "Closed"
|
||||
foo_closed.aasm.human_state.should == "Closed"
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
@ -24,24 +24,24 @@ describe "instance methods" do
|
|||
end
|
||||
|
||||
it "should return the initial state when new and the aasm field is nil" do
|
||||
gate.aasm_current_state.should == :opened
|
||||
gate.aasm.current_state.should == :opened
|
||||
end
|
||||
|
||||
it "should return the aasm column when new and the aasm field is not nil" do
|
||||
gate.aasm_state = "closed"
|
||||
gate.aasm_current_state.should == :closed
|
||||
gate.aasm.current_state.should == :closed
|
||||
end
|
||||
|
||||
it "should return the aasm column when not new and the aasm_column is not nil" do
|
||||
gate.stub(:new_record?).and_return(false)
|
||||
gate.aasm_state = "state"
|
||||
gate.aasm_current_state.should == :state
|
||||
gate.aasm.current_state.should == :state
|
||||
end
|
||||
|
||||
it "should allow a nil state" do
|
||||
gate.stub(:new_record?).and_return(false)
|
||||
gate.aasm_state = nil
|
||||
gate.aasm_current_state.should be_nil
|
||||
gate.aasm.current_state.should be_nil
|
||||
end
|
||||
|
||||
it "should call aasm_ensure_initial_state on validation before create" do
|
||||
|
@ -59,15 +59,11 @@ end
|
|||
|
||||
describe 'subclasses' do
|
||||
it "should have the same states as its parent class" do
|
||||
Derivate.aasm_states.should == Simple.aasm_states
|
||||
DerivateNewDsl.aasm.states.should == SimpleNewDsl.aasm.states
|
||||
end
|
||||
|
||||
it "should have the same events as its parent class" do
|
||||
Derivate.aasm_events.should == Simple.aasm_events
|
||||
end
|
||||
|
||||
it "should have the same column as its parent class" do
|
||||
Derivate.aasm_column.should == :status
|
||||
DerivateNewDsl.aasm.events.should == SimpleNewDsl.aasm.events
|
||||
end
|
||||
|
||||
it "should have the same column as its parent even for the new dsl" do
|
||||
|
@ -76,26 +72,7 @@ describe 'subclasses' do
|
|||
end
|
||||
end
|
||||
|
||||
describe "named scopes with the old DSL" do
|
||||
|
||||
context "Does not already respond_to? the scope name" do
|
||||
it "should add a scope" do
|
||||
Simple.should respond_to(:unknown_scope)
|
||||
SimpleNewDsl.unknown_scope.is_a?(ActiveRecord::Relation).should be_true
|
||||
end
|
||||
end
|
||||
|
||||
context "Already respond_to? the scope name" do
|
||||
it "should not add a scope" do
|
||||
Simple.should respond_to(:new)
|
||||
Simple.new.class.should == Simple
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
describe "named scopes with the new DSL" do
|
||||
|
||||
context "Does not already respond_to? the scope name" do
|
||||
it "should add a scope" do
|
||||
SimpleNewDsl.should respond_to(:unknown_scope)
|
||||
|
@ -119,8 +96,8 @@ end
|
|||
describe 'initial states' do
|
||||
|
||||
it 'should support conditions' do
|
||||
Thief.new(:skilled => true).aasm_current_state.should == :rich
|
||||
Thief.new(:skilled => false).aasm_current_state.should == :jailed
|
||||
Thief.new(:skilled => true).aasm.current_state.should == :rich
|
||||
Thief.new(:skilled => false).aasm.current_state.should == :jailed
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
@ -20,8 +20,7 @@ describe 'state machine' do
|
|||
let(:payment) {Payment.new}
|
||||
|
||||
it 'starts with an initial state' do
|
||||
payment.aasm_current_state.should == :initialised
|
||||
# payment.aasm.current_state.should == :initialised # not yet supported
|
||||
payment.aasm.current_state.should == :initialised
|
||||
payment.should respond_to(:initialised?)
|
||||
payment.should be_initialised
|
||||
end
|
||||
|
|
|
@ -4,18 +4,18 @@ describe 'subclassing' do
|
|||
let(:son) {Son.new}
|
||||
|
||||
it 'should have the parent states' do
|
||||
Foo.aasm_states.each do |state|
|
||||
FooTwo.aasm_states.should include(state)
|
||||
Foo.aasm.states.each do |state|
|
||||
FooTwo.aasm.states.should include(state)
|
||||
end
|
||||
Baz.aasm_states.should == Bar.aasm_states
|
||||
Baz.aasm.states.should == Bar.aasm.states
|
||||
end
|
||||
|
||||
it 'should not add the child states to the parent machine' do
|
||||
Foo.aasm_states.should_not include(:foo)
|
||||
Foo.aasm.states.should_not include(:foo)
|
||||
end
|
||||
|
||||
it "should have the same events as its parent" do
|
||||
Baz.aasm_events.should == Bar.aasm_events
|
||||
Baz.aasm.events.should == Bar.aasm.events
|
||||
end
|
||||
|
||||
it 'should know how to respond to `may_add_details?`' do
|
||||
|
@ -24,8 +24,8 @@ describe 'subclassing' do
|
|||
|
||||
it 'should not break if I call Son#update_state' do
|
||||
son.update_state
|
||||
son.aasm_current_state.should == :pending_details_confirmation
|
||||
son.aasm.current_state.should == :pending_details_confirmation
|
||||
end
|
||||
|
||||
|
||||
end
|
||||
|
||||
|
|
Loading…
Reference in a new issue