aasm 4.5.1 → 5.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +5 -5
- data/LICENSE +1 -1
- data/README.md +809 -129
- data/lib/aasm/aasm.rb +74 -37
- data/lib/aasm/base.rb +188 -41
- data/lib/aasm/configuration.rb +27 -2
- data/lib/aasm/core/event.rb +75 -47
- data/lib/aasm/core/invoker.rb +129 -0
- data/lib/aasm/core/invokers/base_invoker.rb +75 -0
- data/lib/aasm/core/invokers/class_invoker.rb +52 -0
- data/lib/aasm/core/invokers/literal_invoker.rb +49 -0
- data/lib/aasm/core/invokers/proc_invoker.rb +59 -0
- data/lib/aasm/core/state.rb +22 -13
- data/lib/aasm/core/transition.rb +30 -23
- data/lib/aasm/dsl_helper.rb +24 -22
- data/lib/aasm/errors.rb +8 -5
- data/lib/aasm/instance_base.rb +63 -15
- data/lib/aasm/localizer.rb +13 -3
- data/lib/aasm/minitest/allow_event.rb +13 -0
- data/lib/aasm/minitest/allow_transition_to.rb +13 -0
- data/lib/aasm/minitest/have_state.rb +13 -0
- data/lib/aasm/minitest/transition_from.rb +21 -0
- data/lib/aasm/minitest.rb +5 -0
- data/lib/aasm/minitest_spec.rb +15 -0
- data/lib/aasm/persistence/active_record_persistence.rb +87 -79
- data/lib/aasm/persistence/base.rb +30 -30
- data/lib/aasm/persistence/core_data_query_persistence.rb +94 -0
- data/lib/aasm/persistence/dynamoid_persistence.rb +92 -0
- data/lib/aasm/persistence/mongoid_persistence.rb +49 -35
- data/lib/aasm/persistence/no_brainer_persistence.rb +105 -0
- data/lib/aasm/persistence/orm.rb +154 -0
- data/lib/aasm/persistence/plain_persistence.rb +2 -1
- data/lib/aasm/persistence/redis_persistence.rb +112 -0
- data/lib/aasm/persistence/sequel_persistence.rb +37 -67
- data/lib/aasm/persistence.rb +20 -5
- data/lib/aasm/rspec/allow_event.rb +5 -1
- data/lib/aasm/rspec/allow_transition_to.rb +5 -1
- data/lib/aasm/rspec/transition_from.rb +8 -4
- data/lib/aasm/state_machine.rb +6 -12
- data/lib/aasm/state_machine_store.rb +76 -0
- data/lib/aasm/version.rb +1 -1
- data/lib/aasm.rb +8 -2
- data/lib/generators/aasm/aasm_generator.rb +16 -0
- data/lib/generators/aasm/orm_helpers.rb +41 -0
- data/lib/generators/active_record/aasm_generator.rb +40 -0
- data/lib/generators/active_record/templates/migration.rb +8 -0
- data/lib/generators/active_record/templates/migration_existing.rb +5 -0
- data/lib/generators/mongoid/aasm_generator.rb +28 -0
- data/lib/generators/nobrainer/aasm_generator.rb +28 -0
- data/lib/motion-aasm.rb +37 -0
- metadata +104 -259
- data/.document +0 -6
- data/.gitignore +0 -19
- data/.travis.yml +0 -37
- data/API +0 -34
- data/CHANGELOG.md +0 -272
- data/CODE_OF_CONDUCT.md +0 -13
- data/Gemfile +0 -15
- data/HOWTO +0 -12
- data/PLANNED_CHANGES.md +0 -11
- data/README_FROM_VERSION_3_TO_4.md +0 -240
- data/Rakefile +0 -26
- data/aasm.gemspec +0 -31
- data/callbacks.txt +0 -51
- data/gemfiles/rails_3.2.gemfile +0 -14
- data/gemfiles/rails_4.0.gemfile +0 -12
- data/gemfiles/rails_4.0_mongo_mapper.gemfile +0 -14
- data/gemfiles/rails_4.1.gemfile +0 -12
- data/gemfiles/rails_4.1_mongo_mapper.gemfile +0 -14
- data/gemfiles/rails_4.2.gemfile +0 -12
- data/gemfiles/rails_4.2_mongo_mapper.gemfile +0 -14
- data/gemfiles/rails_4.2_mongoid_5.gemfile +0 -12
- data/lib/aasm/persistence/mongo_mapper_persistence.rb +0 -157
- data/spec/database.rb +0 -63
- data/spec/database.yml +0 -3
- data/spec/en.yml +0 -9
- data/spec/en_deprecated_style.yml +0 -10
- data/spec/models/active_record/basic_active_record_two_state_machines_example.rb +0 -25
- data/spec/models/active_record/complex_active_record_example.rb +0 -33
- data/spec/models/active_record/derivate_new_dsl.rb +0 -7
- data/spec/models/active_record/false_state.rb +0 -35
- data/spec/models/active_record/gate.rb +0 -39
- data/spec/models/active_record/localizer_test_model.rb +0 -34
- data/spec/models/active_record/no_direct_assignment.rb +0 -21
- data/spec/models/active_record/no_scope.rb +0 -21
- data/spec/models/active_record/persisted_state.rb +0 -12
- data/spec/models/active_record/provided_and_persisted_state.rb +0 -24
- data/spec/models/active_record/reader.rb +0 -7
- data/spec/models/active_record/readme_job.rb +0 -21
- data/spec/models/active_record/simple_new_dsl.rb +0 -17
- data/spec/models/active_record/thief.rb +0 -29
- data/spec/models/active_record/transient.rb +0 -6
- data/spec/models/active_record/with_enum.rb +0 -39
- data/spec/models/active_record/with_false_enum.rb +0 -31
- data/spec/models/active_record/with_true_enum.rb +0 -39
- data/spec/models/active_record/writer.rb +0 -6
- data/spec/models/basic_two_state_machines_example.rb +0 -25
- data/spec/models/callbacks/basic.rb +0 -78
- data/spec/models/callbacks/basic_multiple.rb +0 -75
- data/spec/models/callbacks/guard_within_block.rb +0 -66
- data/spec/models/callbacks/guard_within_block_multiple.rb +0 -66
- data/spec/models/callbacks/multiple_transitions_transition_guard.rb +0 -65
- data/spec/models/callbacks/multiple_transitions_transition_guard_multiple.rb +0 -65
- data/spec/models/callbacks/private_method.rb +0 -44
- data/spec/models/callbacks/private_method_multiple.rb +0 -44
- data/spec/models/callbacks/with_args.rb +0 -61
- data/spec/models/callbacks/with_args_multiple.rb +0 -61
- data/spec/models/callbacks/with_state_arg.rb +0 -26
- data/spec/models/callbacks/with_state_arg_multiple.rb +0 -26
- data/spec/models/complex_example.rb +0 -222
- data/spec/models/conversation.rb +0 -93
- data/spec/models/default_state.rb +0 -12
- data/spec/models/double_definer.rb +0 -21
- data/spec/models/foo.rb +0 -92
- data/spec/models/foo_callback_multiple.rb +0 -45
- data/spec/models/guardian.rb +0 -48
- data/spec/models/guardian_multiple.rb +0 -48
- data/spec/models/initial_state_proc.rb +0 -31
- data/spec/models/invalid_persistor.rb +0 -31
- data/spec/models/mongo_mapper/complex_mongo_mapper_example.rb +0 -37
- data/spec/models/mongo_mapper/no_scope_mongo_mapper.rb +0 -21
- data/spec/models/mongo_mapper/simple_mongo_mapper.rb +0 -23
- data/spec/models/mongo_mapper/simple_new_dsl_mongo_mapper.rb +0 -25
- data/spec/models/mongoid/complex_mongoid_example.rb +0 -37
- data/spec/models/mongoid/no_scope_mongoid.rb +0 -21
- data/spec/models/mongoid/simple_mongoid.rb +0 -23
- data/spec/models/mongoid/simple_new_dsl_mongoid.rb +0 -25
- data/spec/models/no_initial_state.rb +0 -25
- data/spec/models/not_auto_loaded/process.rb +0 -21
- data/spec/models/parametrised_event.rb +0 -29
- data/spec/models/parametrised_event_multiple.rb +0 -29
- data/spec/models/process_with_new_dsl.rb +0 -31
- data/spec/models/provided_state.rb +0 -24
- data/spec/models/sequel/complex_sequel_example.rb +0 -45
- data/spec/models/sequel/sequel_multiple.rb +0 -25
- data/spec/models/sequel/sequel_simple.rb +0 -25
- data/spec/models/silencer.rb +0 -27
- data/spec/models/simple_example.rb +0 -15
- data/spec/models/simple_multiple_example.rb +0 -30
- data/spec/models/state_machine_with_failed_event.rb +0 -12
- data/spec/models/sub_class.rb +0 -7
- data/spec/models/sub_class_with_more_states.rb +0 -18
- data/spec/models/sub_classing.rb +0 -3
- data/spec/models/super_class.rb +0 -46
- data/spec/models/this_name_better_not_be_in_use.rb +0 -11
- data/spec/models/transactor.rb +0 -53
- data/spec/models/valid_state_name.rb +0 -23
- data/spec/models/validator.rb +0 -79
- data/spec/models/worker.rb +0 -2
- data/spec/spec_helper.rb +0 -25
- data/spec/unit/api_spec.rb +0 -77
- data/spec/unit/basic_two_state_machines_example_spec.rb +0 -10
- data/spec/unit/callback_multiple_spec.rb +0 -295
- data/spec/unit/callbacks_spec.rb +0 -296
- data/spec/unit/complex_example_spec.rb +0 -84
- data/spec/unit/complex_multiple_example_spec.rb +0 -99
- data/spec/unit/edge_cases_spec.rb +0 -16
- data/spec/unit/event_multiple_spec.rb +0 -73
- data/spec/unit/event_naming_spec.rb +0 -11
- data/spec/unit/event_spec.rb +0 -322
- data/spec/unit/guard_multiple_spec.rb +0 -60
- data/spec/unit/guard_spec.rb +0 -60
- data/spec/unit/initial_state_multiple_spec.rb +0 -15
- data/spec/unit/initial_state_spec.rb +0 -12
- data/spec/unit/inspection_multiple_spec.rb +0 -201
- data/spec/unit/inspection_spec.rb +0 -111
- data/spec/unit/localizer_spec.rb +0 -76
- data/spec/unit/memory_leak_spec.rb +0 -38
- data/spec/unit/new_dsl_spec.rb +0 -12
- data/spec/unit/persistence/active_record_persistence_multiple_spec.rb +0 -573
- data/spec/unit/persistence/active_record_persistence_spec.rb +0 -552
- data/spec/unit/persistence/mongo_mapper_persistence_multiple_spec.rb +0 -146
- data/spec/unit/persistence/mongo_mapper_persistence_spec.rb +0 -93
- data/spec/unit/persistence/mongoid_persistence_multiple_spec.rb +0 -127
- data/spec/unit/persistence/mongoid_persistence_spec.rb +0 -79
- data/spec/unit/persistence/sequel_persistence_multiple_spec.rb +0 -153
- data/spec/unit/persistence/sequel_persistence_spec.rb +0 -100
- data/spec/unit/readme_spec.rb +0 -42
- data/spec/unit/reloading_spec.rb +0 -15
- data/spec/unit/rspec_matcher_spec.rb +0 -79
- data/spec/unit/simple_example_spec.rb +0 -42
- data/spec/unit/simple_multiple_example_spec.rb +0 -63
- data/spec/unit/state_spec.rb +0 -89
- data/spec/unit/subclassing_multiple_spec.rb +0 -39
- data/spec/unit/subclassing_spec.rb +0 -31
- data/spec/unit/transition_spec.rb +0 -291
data/lib/aasm/core/transition.rb
CHANGED
@@ -1,18 +1,21 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module AASM::Core
|
2
4
|
class Transition
|
3
|
-
include DslHelper
|
5
|
+
include AASM::DslHelper
|
4
6
|
|
5
|
-
attr_reader :from, :to, :event, :opts
|
7
|
+
attr_reader :from, :to, :event, :opts, :failures
|
6
8
|
alias_method :options, :opts
|
7
9
|
|
8
10
|
def initialize(event, opts, &block)
|
9
|
-
add_options_from_dsl(opts, [:on_transition, :guard, :after], &block) if block
|
11
|
+
add_options_from_dsl(opts, [:on_transition, :guard, :after, :success], &block) if block
|
10
12
|
|
11
13
|
@event = event
|
12
14
|
@from = opts[:from]
|
13
15
|
@to = opts[:to]
|
14
16
|
@guards = Array(opts[:guards]) + Array(opts[:guard]) + Array(opts[:if])
|
15
17
|
@unless = Array(opts[:unless]) #TODO: This could use a better name
|
18
|
+
@failures = []
|
16
19
|
|
17
20
|
if opts[:on_transition]
|
18
21
|
warn '[DEPRECATION] :on_transition is deprecated, use :after instead'
|
@@ -21,9 +24,21 @@ module AASM::Core
|
|
21
24
|
@after = Array(opts[:after])
|
22
25
|
@after = @after[0] if @after.size == 1
|
23
26
|
|
27
|
+
@success = Array(opts[:success])
|
28
|
+
@success = @success[0] if @success.size == 1
|
29
|
+
|
24
30
|
@opts = opts
|
25
31
|
end
|
26
32
|
|
33
|
+
# called internally by Ruby 1.9 after clone()
|
34
|
+
def initialize_copy(orig)
|
35
|
+
super
|
36
|
+
@guards = @guards.dup
|
37
|
+
@unless = @unless.dup
|
38
|
+
@opts = {}
|
39
|
+
orig.opts.each_pair { |name, setting| @opts[name] = setting.is_a?(Hash) || setting.is_a?(Array) ? setting.dup : setting }
|
40
|
+
end
|
41
|
+
|
27
42
|
def allowed?(obj, *args)
|
28
43
|
invoke_callbacks_compatible_with_guard(@guards, obj, args, :guard => true) &&
|
29
44
|
invoke_callbacks_compatible_with_guard(@unless, obj, args, :unless => true)
|
@@ -42,6 +57,10 @@ module AASM::Core
|
|
42
57
|
@from == value
|
43
58
|
end
|
44
59
|
|
60
|
+
def invoke_success_callbacks(obj, *args)
|
61
|
+
_fire_callbacks(@success, obj, args)
|
62
|
+
end
|
63
|
+
|
45
64
|
private
|
46
65
|
|
47
66
|
def invoke_callbacks_compatible_with_guard(code, record, args, options={})
|
@@ -50,26 +69,14 @@ module AASM::Core
|
|
50
69
|
record.aasm(event.state_machine.name).to_state = @to if record.aasm(event.state_machine.name).respond_to?(:to_state=)
|
51
70
|
end
|
52
71
|
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
# invoke guard callbacks
|
62
|
-
code.all? {|a| invoke_callbacks_compatible_with_guard(a, record, args)}
|
63
|
-
elsif options[:unless]
|
64
|
-
# invoke unless callbacks
|
65
|
-
code.all? {|a| !invoke_callbacks_compatible_with_guard(a, record, args)}
|
66
|
-
else
|
67
|
-
# invoke after callbacks
|
68
|
-
code.map {|a| invoke_callbacks_compatible_with_guard(a, record, args)}
|
69
|
-
end
|
70
|
-
else
|
71
|
-
true
|
72
|
-
end
|
72
|
+
Invoker.new(code, record, args)
|
73
|
+
.with_options(options)
|
74
|
+
.with_failures(failures)
|
75
|
+
.invoke
|
76
|
+
end
|
77
|
+
|
78
|
+
def _fire_callbacks(code, record, args)
|
79
|
+
Invoker.new(code, record, args).invoke
|
73
80
|
end
|
74
81
|
|
75
82
|
end
|
data/lib/aasm/dsl_helper.rb
CHANGED
@@ -1,30 +1,32 @@
|
|
1
|
-
module
|
1
|
+
module AASM
|
2
|
+
module DslHelper
|
2
3
|
|
3
|
-
|
4
|
-
|
4
|
+
class Proxy
|
5
|
+
attr_accessor :options
|
5
6
|
|
6
|
-
|
7
|
-
|
8
|
-
|
7
|
+
def initialize(options, valid_keys, source)
|
8
|
+
@valid_keys = valid_keys
|
9
|
+
@source = source
|
9
10
|
|
10
|
-
|
11
|
-
|
11
|
+
@options = options
|
12
|
+
end
|
12
13
|
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
14
|
+
def method_missing(name, *args, &block)
|
15
|
+
if @valid_keys.include?(name)
|
16
|
+
options[name] = Array(options[name])
|
17
|
+
options[name] << block if block
|
18
|
+
options[name] += Array(args)
|
19
|
+
else
|
20
|
+
@source.send name, *args, &block
|
21
|
+
end
|
20
22
|
end
|
21
23
|
end
|
22
|
-
end
|
23
24
|
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
25
|
+
def add_options_from_dsl(options, valid_keys, &block)
|
26
|
+
proxy = Proxy.new(options, valid_keys, self)
|
27
|
+
proxy.instance_eval(&block)
|
28
|
+
proxy.options
|
29
|
+
end
|
29
30
|
|
30
|
-
end
|
31
|
+
end
|
32
|
+
end
|
data/lib/aasm/errors.rb
CHANGED
@@ -3,17 +3,20 @@ module AASM
|
|
3
3
|
class UnknownStateMachineError < RuntimeError; end
|
4
4
|
|
5
5
|
class InvalidTransition < RuntimeError
|
6
|
-
attr_reader :object, :event_name, :state_machine_name
|
6
|
+
attr_reader :object, :event_name, :originating_state, :failures, :state_machine_name
|
7
7
|
|
8
|
-
def initialize(object, event_name, state_machine_name)
|
9
|
-
@object, @event_name, @
|
8
|
+
def initialize(object, event_name, state_machine_name, failures = [])
|
9
|
+
@object, @event_name, @originating_state, @failures = object, event_name, object.aasm(state_machine_name).current_state, failures
|
10
|
+
@state_machine_name = state_machine_name
|
11
|
+
super("Event '#{event_name}' cannot transition from '#{originating_state}'.#{reasoning}")
|
10
12
|
end
|
11
13
|
|
12
|
-
def
|
13
|
-
"
|
14
|
+
def reasoning
|
15
|
+
" Failed callback(s): #{failures}." unless failures.empty?
|
14
16
|
end
|
15
17
|
end
|
16
18
|
|
17
19
|
class UndefinedState < RuntimeError; end
|
20
|
+
class UndefinedEvent < UndefinedState; end
|
18
21
|
class NoDirectAssignmentError < RuntimeError; end
|
19
22
|
end
|
data/lib/aasm/instance_base.rb
CHANGED
@@ -1,6 +1,5 @@
|
|
1
1
|
module AASM
|
2
2
|
class InstanceBase
|
3
|
-
|
4
3
|
attr_accessor :from_state, :to_state, :current_event
|
5
4
|
|
6
5
|
def initialize(instance, name=:default) # instance of the class including AASM, name of the state machine
|
@@ -14,7 +13,6 @@ module AASM
|
|
14
13
|
|
15
14
|
def current_state=(state)
|
16
15
|
@instance.aasm_write_state_without_persistence(state, @name)
|
17
|
-
# @current_state = state
|
18
16
|
end
|
19
17
|
|
20
18
|
def enter_initial_state
|
@@ -22,7 +20,6 @@ module AASM
|
|
22
20
|
state_object = state_object_for_name(state_name)
|
23
21
|
|
24
22
|
state_object.fire_callbacks(:before_enter, @instance)
|
25
|
-
# state_object.fire_callbacks(:enter, @instance)
|
26
23
|
self.current_state = state_name
|
27
24
|
state_object.fire_callbacks(:after_enter, @instance)
|
28
25
|
|
@@ -30,37 +27,67 @@ module AASM
|
|
30
27
|
end
|
31
28
|
|
32
29
|
def human_state
|
33
|
-
|
30
|
+
state_object_for_name(current_state).display_name
|
34
31
|
end
|
35
32
|
|
36
|
-
def states(options={})
|
37
|
-
if options
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
33
|
+
def states(options={}, *args)
|
34
|
+
if options.has_key?(:permitted)
|
35
|
+
selected_events = events({:permitted => options[:permitted]}, *args)
|
36
|
+
# An array of arrays. Each inner array represents the transitions that
|
37
|
+
# transition from the current state for an event
|
38
|
+
event_transitions = selected_events.map {|e| e.transitions_from_state(current_state) }
|
39
|
+
|
40
|
+
# An array of :to transition states
|
41
|
+
to_state_names = event_transitions.map do |transitions|
|
42
|
+
return nil if transitions.empty?
|
43
|
+
|
44
|
+
# Return the :to state of the first transition that is allowed (or not) or nil
|
45
|
+
if options[:permitted]
|
46
|
+
transition = transitions.find { |t| t.allowed?(@instance, *args) }
|
47
|
+
else
|
48
|
+
transition = transitions.find { |t| !t.allowed?(@instance, *args) }
|
49
|
+
end
|
50
|
+
transition ? transition.to : nil
|
51
|
+
end.flatten.compact.uniq
|
52
|
+
|
53
|
+
# Select states that are in to_state_names
|
54
|
+
@instance.class.aasm(@name).states.select {|s| to_state_names.include?(s.name)}
|
43
55
|
else
|
44
56
|
@instance.class.aasm(@name).states
|
45
57
|
end
|
46
58
|
end
|
47
59
|
|
48
|
-
def events(options={})
|
60
|
+
def events(options={}, *args)
|
49
61
|
state = options[:state] || current_state
|
50
62
|
events = @instance.class.aasm(@name).events.select {|e| e.transitions_from_state?(state) }
|
51
63
|
|
52
64
|
options[:reject] = Array(options[:reject])
|
53
65
|
events.reject! { |e| options[:reject].include?(e.name) }
|
54
66
|
|
55
|
-
if options
|
67
|
+
if options.has_key?(:permitted)
|
56
68
|
# filters the results of events_for_current_state so that only those that
|
57
69
|
# are really currently possible (given transition guards) are shown.
|
58
|
-
|
70
|
+
if options[:permitted]
|
71
|
+
events.select! { |e| @instance.send("may_#{e.name}?", *args) }
|
72
|
+
else
|
73
|
+
events.select! { |e| !@instance.send("may_#{e.name}?", *args) }
|
74
|
+
end
|
59
75
|
end
|
60
76
|
|
61
77
|
events
|
62
78
|
end
|
63
79
|
|
80
|
+
def permitted_transitions
|
81
|
+
events(permitted: true).flat_map do |event|
|
82
|
+
available_transitions = event.transitions_from_state(current_state)
|
83
|
+
allowed_transitions = available_transitions.select { |t| t.allowed?(@instance) }
|
84
|
+
|
85
|
+
allowed_transitions.map do |transition|
|
86
|
+
{ event: event.name, state: transition.to }
|
87
|
+
end
|
88
|
+
end
|
89
|
+
end
|
90
|
+
|
64
91
|
def state_object_for_name(name)
|
65
92
|
obj = @instance.class.aasm(@name).states.find {|s| s.name == name}
|
66
93
|
raise AASM::UndefinedState, "State :#{name} doesn't exist" if obj.nil?
|
@@ -74,7 +101,7 @@ module AASM
|
|
74
101
|
when Proc
|
75
102
|
state.call(@instance)
|
76
103
|
else
|
77
|
-
raise NotImplementedError, "Unrecognized state-type given.
|
104
|
+
raise NotImplementedError, "Unrecognized state-type given. Expected Symbol, String, or Proc."
|
78
105
|
end
|
79
106
|
end
|
80
107
|
|
@@ -86,11 +113,32 @@ module AASM
|
|
86
113
|
end
|
87
114
|
end
|
88
115
|
|
116
|
+
def fire(event_name, *args, &block)
|
117
|
+
event_exists?(event_name)
|
118
|
+
|
119
|
+
@instance.send(event_name, *args, &block)
|
120
|
+
end
|
121
|
+
|
122
|
+
def fire!(event_name, *args, &block)
|
123
|
+
event_exists?(event_name, true)
|
124
|
+
bang_event_name = "#{event_name}!".to_sym
|
125
|
+
@instance.send(bang_event_name, *args, &block)
|
126
|
+
end
|
127
|
+
|
89
128
|
def set_current_state_with_persistence(state)
|
90
129
|
save_success = @instance.aasm_write_state(state, @name)
|
91
130
|
self.current_state = state if save_success
|
92
131
|
save_success
|
93
132
|
end
|
94
133
|
|
134
|
+
private
|
135
|
+
|
136
|
+
def event_exists?(event_name, bang = false)
|
137
|
+
event = @instance.class.aasm(@name).state_machine.events[event_name.to_sym]
|
138
|
+
return true if event
|
139
|
+
|
140
|
+
event_error = bang ? "#{event_name}!" : event_name
|
141
|
+
raise AASM::UndefinedEvent, "Event :#{event_error} doesn't exist" if event.nil?
|
142
|
+
end
|
95
143
|
end
|
96
144
|
end
|
data/lib/aasm/localizer.rb
CHANGED
@@ -5,7 +5,7 @@ module AASM
|
|
5
5
|
list << :"#{i18n_scope(klass)}.events.#{i18n_klass(ancestor)}.#{event}"
|
6
6
|
list
|
7
7
|
end
|
8
|
-
translate_queue(checklist) || I18n.translate(checklist.shift, :default => event
|
8
|
+
translate_queue(checklist) || I18n.translate(checklist.shift, :default => default_display_name(event))
|
9
9
|
end
|
10
10
|
|
11
11
|
def human_state_name(klass, state)
|
@@ -14,7 +14,7 @@ module AASM
|
|
14
14
|
list << item_for(klass, state, ancestor, :old_style => true)
|
15
15
|
list
|
16
16
|
end
|
17
|
-
translate_queue(checklist) || I18n.translate(checklist.shift, :default => state
|
17
|
+
translate_queue(checklist) || I18n.translate(checklist.shift, :default => default_display_name(state))
|
18
18
|
end
|
19
19
|
|
20
20
|
private
|
@@ -46,8 +46,18 @@ module AASM
|
|
46
46
|
end
|
47
47
|
|
48
48
|
def ancestors_list(klass)
|
49
|
+
has_active_record_base = defined?(::ActiveRecord::Base)
|
49
50
|
klass.ancestors.select do |ancestor|
|
50
|
-
|
51
|
+
not_active_record_base = has_active_record_base ? (ancestor != ::ActiveRecord::Base) : true
|
52
|
+
ancestor.respond_to?(:model_name) && not_active_record_base
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
def default_display_name(object) # Can use better arguement name
|
57
|
+
if object.respond_to?(:default_display_name)
|
58
|
+
object.default_display_name
|
59
|
+
else
|
60
|
+
object.to_s.gsub(/_/, ' ').capitalize
|
51
61
|
end
|
52
62
|
end
|
53
63
|
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
module Minitest::Assertions
|
2
|
+
def assert_event_allowed(object, event, options = {})
|
3
|
+
state_machine_name = options.fetch(:on, :default)
|
4
|
+
assert object.aasm(state_machine_name).may_fire_event?(event),
|
5
|
+
"Expected that the event :#{event} would be allowed (on :#{state_machine_name})"
|
6
|
+
end
|
7
|
+
|
8
|
+
def refute_event_allowed(object, event, options = {})
|
9
|
+
state_machine_name = options.fetch(:on, :default)
|
10
|
+
refute object.aasm(state_machine_name).may_fire_event?(event),
|
11
|
+
"Expected that the event :#{event} would not be allowed (on :#{state_machine_name})"
|
12
|
+
end
|
13
|
+
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
module Minitest::Assertions
|
2
|
+
def assert_transition_to_allowed(object, to_state, options = {})
|
3
|
+
state_machine_name = options.fetch(:on, :default)
|
4
|
+
assert object.aasm(state_machine_name).states(permitted: true).include?(to_state),
|
5
|
+
"Expected that the state :#{to_state} would be reachable (on :#{state_machine_name})"
|
6
|
+
end
|
7
|
+
|
8
|
+
def refute_transition_to_allowed(object, to_state, options = {})
|
9
|
+
state_machine_name = options.fetch(:on, :default)
|
10
|
+
refute object.aasm(state_machine_name).states(permitted: true).include?(to_state),
|
11
|
+
"Expected that the state :#{to_state} would be reachable (on :#{state_machine_name})"
|
12
|
+
end
|
13
|
+
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
module Minitest::Assertions
|
2
|
+
def assert_have_state(object, state, options = {})
|
3
|
+
state_machine_name = options.fetch(:on, :default)
|
4
|
+
assert object.aasm(state_machine_name).current_state == state,
|
5
|
+
"Expected that :#{object.aasm(state_machine_name).current_state} would be :#{state} (on :#{state_machine_name})"
|
6
|
+
end
|
7
|
+
|
8
|
+
def refute_have_state(object, state, options = {})
|
9
|
+
state_machine_name = options.fetch(:on, :default)
|
10
|
+
refute object.aasm(state_machine_name).current_state == state,
|
11
|
+
"Expected that :#{object.aasm(state_machine_name).current_state} would be :#{state} (on :#{state_machine_name})"
|
12
|
+
end
|
13
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
module Minitest::Assertions
|
2
|
+
def assert_transitions_from(object, from_state, *args)
|
3
|
+
options = args.first
|
4
|
+
options[:on] ||= :default
|
5
|
+
assert _transitions_from?(object, from_state, args, options),
|
6
|
+
"Expected transition state to :#{options[:to]} from :#{from_state} on event :#{options[:on_event]}, (on :#{options[:on]})"
|
7
|
+
end
|
8
|
+
|
9
|
+
def refute_transitions_from(object, from_state, *args)
|
10
|
+
options = args.first
|
11
|
+
options[:on] ||= :default
|
12
|
+
refute _transitions_from?(object, from_state, args, options),
|
13
|
+
"Expected transition state to :#{options[:to]} from :#{from_state} on event :#{options[:on_event]}, (on :#{options[:on]})"
|
14
|
+
end
|
15
|
+
|
16
|
+
def _transitions_from?(object, from_state, args, options)
|
17
|
+
state_machine_name = options[:on]
|
18
|
+
object.aasm(state_machine_name).current_state = from_state.to_sym
|
19
|
+
object.send(options[:on_event], *args) && options[:to].to_sym == object.aasm(state_machine_name).current_state
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
require 'aasm/minitest'
|
2
|
+
|
3
|
+
module Minitest::Expectations
|
4
|
+
AASM.infect_an_assertion :assert_transitions_from, :must_transition_from, :do_not_flip
|
5
|
+
AASM.infect_an_assertion :refute_transitions_from, :wont_transition_from, :do_not_flip
|
6
|
+
|
7
|
+
AASM.infect_an_assertion :assert_transition_to_allowed, :must_allow_transition_to, :do_not_flip
|
8
|
+
AASM.infect_an_assertion :refute_transition_to_allowed, :wont_allow_transition_to, :do_not_flip
|
9
|
+
|
10
|
+
AASM.infect_an_assertion :assert_have_state, :must_have_state, :do_not_flip
|
11
|
+
AASM.infect_an_assertion :refute_have_state, :wont_have_state, :do_not_flip
|
12
|
+
|
13
|
+
AASM.infect_an_assertion :assert_event_allowed, :must_allow_event, :do_not_flip
|
14
|
+
AASM.infect_an_assertion :refute_event_allowed, :wont_allow_event, :do_not_flip
|
15
|
+
end
|