aasm 4.3.0 → 4.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 1b51607dcaee12f000a23ee83033925bf03dcee7
4
- data.tar.gz: c367dd718de8264432f332ff626fc8aff05581e3
3
+ metadata.gz: 92b6a0df28245debe06c0ecbd3bd95e91b0cf323
4
+ data.tar.gz: 99bfa6652b17a26388b073ee431a1878ce961a4e
5
5
  SHA512:
6
- metadata.gz: 4a3750ab5b7758679ed9ca66fc35f04cf69347a09bc03070fd514ccbd3c111f129f907e6c4e387cf253441daf7e8e79a1045ea64da43296803434711c56a2b84
7
- data.tar.gz: d82ff5d11b0ebae4112277283706e3bd9774517e6f4a7bece806360deda054c811ccebccfefd59c05244dd05e5351f21672932ba8071a8c2626077ba76bc585d
6
+ metadata.gz: d6cf5a7eea74d1c20108d48370d0f6048722efefb6af0110c70de56dd13032bcaabf57749add95ae25dc086faab8cbb5dcf9ad08ad4cafbafdfb400481ce1fd4
7
+ data.tar.gz: 90a92ba66f2b4d67c898a9076f324e0c99ce768aa5160f6d70dc74bca48e8ba4cf95317bf5e203b66985e9dcd77a52fb814dc65cc45f498dfeab20fde31fecb8
data/.travis.yml CHANGED
@@ -18,11 +18,12 @@ services: mongodb
18
18
  gemfile:
19
19
  - gemfiles/rails_3.2.gemfile
20
20
  - gemfiles/rails_4.0.gemfile
21
- - gemfiles/rails_4.0_bson1.gemfile
21
+ - gemfiles/rails_4.0_mongo_mapper.gemfile
22
22
  - gemfiles/rails_4.1.gemfile
23
- - gemfiles/rails_4.1_bson1.gemfile
23
+ - gemfiles/rails_4.1_mongo_mapper.gemfile
24
24
  - gemfiles/rails_4.2.gemfile
25
- - gemfiles/rails_4.2_bson1.gemfile
25
+ - gemfiles/rails_4.2_mongoid_5.gemfile
26
+ - gemfiles/rails_4.2_mongo_mapper.gemfile
26
27
 
27
28
  matrix:
28
29
  allow_failures:
data/CHANGELOG.md CHANGED
@@ -1,5 +1,19 @@
1
1
  # CHANGELOG
2
2
 
3
+ ## 4.5.0
4
+
5
+ * add RSpec matchers `have_state`, `allow_event` and `allow_transition_to` (see [issue #147](https://github.com/aasm/aasm/issues/147) for details)
6
+ * add RSpec matcher `transition_from` (see [issue #178](https://github.com/aasm/aasm/issues/178) for details, thanks to [@thomasstephane](https://github.com/thomasstephane))
7
+
8
+ ## 4.4.1
9
+
10
+ * add support for rejecting certain events on inspection (see [issue #272](https://github.com/aasm/aasm/issues/272) for details, thanks to [@dubroe](https://github.com/dubroe))
11
+
12
+ ## 4.4.0
13
+
14
+ * add support global transation callbacks (see [issue #221](https://github.com/aasm/aasm/issues/221) and [issue #253](https://github.com/aasm/aasm/issues/253) for details)
15
+ * add support (bugfix) for Mongoid >= 5.0 (see [issue #277](https://github.com/aasm/aasm/issues/277) and [issue #278](https://github.com/aasm/aasm/issues/278) for details)
16
+
3
17
  ## 4.3.0
4
18
 
5
19
  * add support for multiple state machines per class (see [issue #158](https://github.com/aasm/aasm/issues/158) and [issue #240](https://github.com/aasm/aasm/issues/240) for details)
data/PLANNED_CHANGES.md CHANGED
@@ -4,24 +4,8 @@
4
4
 
5
5
  * drop support for aasm_column ?
6
6
 
7
+
7
8
  # Currently working on
8
9
 
9
10
 
10
11
  # Changes so far
11
-
12
- ## version 4.3
13
-
14
- * add support for multiple state machines per class
15
- * class- and instance-level `aasm` methods accept a state machine selector
16
- (aka the state machine _name_)
17
- * if no selector/name is provided, `:default` will be used
18
- * duplicate definitions of states and events will issue warnings
19
- * check all tests
20
- * _ActiveRecord_
21
- * _Mongoid_
22
- * _MongoMapper_
23
- * _Sequel_
24
- * what happen's if someone accesses `aasm`, but has defined a
25
- state machine for `aasm(:my_name)`?
26
- * documentation
27
- * drop support for find_in_state, count_in_state, calculate_in_state, with_state_scope
data/README.md CHANGED
@@ -98,6 +98,8 @@ class Job
98
98
  state :sleeping, :initial => true, :before_enter => :do_something
99
99
  state :running
100
100
 
101
+ after_all_transitions :log_status_change
102
+
101
103
  event :run, :after => :notify_somebody do
102
104
  before do
103
105
  log('Preparing to run')
@@ -117,6 +119,10 @@ class Job
117
119
  end
118
120
  end
119
121
 
122
+ def log_status_change
123
+ puts "changing from #{aasm.from_state} to #{aasm.to_state} (event: #{aasm.current_event})"
124
+ end
125
+
120
126
  def set_process(name)
121
127
  ...
122
128
  end
@@ -145,6 +151,7 @@ begin
145
151
  transition guards
146
152
  old_state before_exit
147
153
  old_state exit
154
+ after_all_transitions
148
155
  transition after
149
156
  new_state before_enter
150
157
  new_state enter
@@ -172,8 +179,9 @@ Note that when passing arguments to a state transition, the first argument must
172
179
  In case of an error during the event processing the error is rescued and passed to `:error`
173
180
  callback, which can handle it or re-raise it for further propagation.
174
181
 
175
- During the transition's `:after` callback (and reliably only then) you can access the
176
- originating state (the from-state) and the target state (the to state), like this:
182
+ During the transition's `:after` callback (and reliably only then, or in the global
183
+ `after_all_transitions` callback) you can access the originating state (the from-state)
184
+ and the target state (the to state), like this:
177
185
 
178
186
  ```ruby
179
187
  def set_process(name)
@@ -313,9 +321,9 @@ job.aasm.current_state # stage3
313
321
  ```
314
322
 
315
323
 
316
- ### Multiple state machine per class
324
+ ### Multiple state machines per class
317
325
 
318
- Multiple state machines per class are supported. Be aware though, that _AASM_ has been
326
+ Multiple state machines per class are supported. Be aware though that _AASM_ has been
319
327
  built with one state machine per class in mind. Nonetheless, here's how to do it:
320
328
 
321
329
  ```ruby
@@ -365,9 +373,9 @@ simple.aasm(:work).current
365
373
 
366
374
  ```
367
375
 
368
- _AASM_ doesn't prohibit to define the same event in both state machines. The
369
- latest definition "wins" and overrides previous definitions. A warning is issued:
370
- `SimpleMultipleExample: The event name run is already used!`.
376
+ _AASM_ doesn't prohibit to define the same event in more than one state machine. The
377
+ latest definition "wins" and overrides previous definitions. Nonetheless, a warning is issued:
378
+ `SimpleMultipleExample: The aasm event name run is already used!`.
371
379
 
372
380
  All _AASM_ class- and instance-level `aasm` methods accept a state machine selector.
373
381
  So, for example, to use inspection on a class level, you have to use
@@ -378,7 +386,7 @@ SimpleMultipleExample.aasm(:work).states
378
386
  ```
379
387
 
380
388
  *Final note*: Support for multiple state machines per class is a pretty new feature
381
- (since version `4.3`), so please bear with us in case it doesn't as expected.
389
+ (since version `4.3`), so please bear with us in case it doesn't work as expected.
382
390
 
383
391
 
384
392
 
@@ -417,7 +425,7 @@ job.run! # saved
417
425
 
418
426
  Saving includes running all validations on the `Job` class. If you want make sure
419
427
  the state gets saved without running validations (and thereby maybe persisting an
420
- invalid object state), simply tell AASM to skip the validations. Be aware, that
428
+ invalid object state), simply tell AASM to skip the validations. Be aware that
421
429
  when skipping validations, only the state column will be updated in the database
422
430
  (just like ActiveRecord `change_column` is working).
423
431
 
@@ -704,9 +712,50 @@ job.aasm.states(:permitted => true).map(&:name)
704
712
  # show all possible (triggerable) events (allowed by transitions)
705
713
  job.aasm.events.map(&:name)
706
714
  => [:sleep]
715
+ job.aasm.events(:reject => :sleep).map(&:name)
716
+ => []
717
+
718
+ # list states for select
719
+ Job.aasm.states_for_select
720
+ => [["Sleeping", "sleeping"], ["Running", "running"], ["Cleaning", "cleaning"]]
707
721
  ```
708
722
 
709
723
 
724
+ ### Testing
725
+
726
+ AASM provides some matchers for [RSpec](http://rspec.info): `transition_from`, `have_state`, `allow_event` and `allow_transition_to`. Add `require 'aasm/rspec'` to your `spec_helper.rb` file and use them like this
727
+
728
+ ```ruby
729
+ # classes with only the default state machine
730
+ job = Job.new
731
+ expect(job).to transition_from(:sleeping).to(:running).on_event(:run)
732
+ expect(job).not_to transition_from(:sleeping).to(:cleaning).on_event(:run)
733
+ expect(job).to have_state(:sleeping)
734
+ expect(job).not_to have_state(:running)
735
+ expect(job).to allow_event :run
736
+ expect(job).to_not allow_event :clean
737
+ expect(job).to allow_transition_to(:running)
738
+ expect(job).to_not allow_transition_to(:cleaning)
739
+
740
+ # classes with multiple state machine
741
+ multiple = SimpleMultipleExample.new
742
+ expect(multiple).to transition_from(:standing).to(:walking).on_event(:walk).on(:move)
743
+ expect(multiple).to_not transition_from(:standing).to(:running).on_event(:walk).on(:move)
744
+ expect(multiple).to have_state(:standing).on(:move)
745
+ expect(multiple).not_to have_state(:walking).on(:move)
746
+ expect(multiple).to allow_event(:walk).on(:move)
747
+ expect(multiple).to_not allow_event(:hold).on(:move)
748
+ expect(multiple).to allow_transition_to(:walking).on(:move)
749
+ expect(multiple).to_not allow_transition_to(:running).on(:move)
750
+ expect(multiple).to transition_from(:sleeping).to(:processing).on_event(:start).on(:work)
751
+ expect(multiple).to_not transition_from(:sleeping).to(:sleeping).on_event(:start).on(:work)
752
+ expect(multiple).to have_state(:sleeping).on(:work)
753
+ expect(multiple).not_to have_state(:processing).on(:work)
754
+ expect(multiple).to allow_event(:start).on(:move)
755
+ expect(multiple).to_not allow_event(:stop).on(:move)
756
+ expect(multiple).to allow_transition_to(:processing).on(:move)
757
+ expect(multiple).to_not allow_transition_to(:sleeping).on(:move)
758
+ ```
710
759
 
711
760
  ## <a id="installation">Installation ##
712
761
 
@@ -0,0 +1,12 @@
1
+ source "https://rubygems.org"
2
+
3
+ gem "sqlite3", :platforms => :ruby
4
+ gem 'rubysl', :platforms => :rbx
5
+ gem 'rubinius-developer_tools', :platforms => :rbx
6
+ gem "jruby-openssl", :platforms => :jruby
7
+ gem "activerecord-jdbcsqlite3-adapter", :platforms => :jruby
8
+ gem "rails", "4.2.0"
9
+ gem 'mongoid', '~>5.0' if Gem::Version.create(RUBY_VERSION.dup) >= Gem::Version.create('1.9.3')
10
+ gem 'sequel'
11
+
12
+ gemspec :path => "../"
data/lib/aasm/base.rb CHANGED
@@ -67,7 +67,7 @@ module AASM
67
67
  @state_machine.add_state(name, @klass, options)
68
68
 
69
69
  if @klass.instance_methods.include?("#{name}?")
70
- warn "#{@klass.name}: The state name #{name} is already used!"
70
+ warn "#{@klass.name}: The aasm state name #{name} is already used!"
71
71
  end
72
72
 
73
73
  @klass.class_eval <<-EORUBY, __FILE__, __LINE__ + 1
@@ -86,7 +86,7 @@ module AASM
86
86
  @state_machine.add_event(name, options, &block)
87
87
 
88
88
  if @klass.instance_methods.include?("may_#{name}?".to_sym)
89
- warn "#{@klass.name}: The event name #{name} is already used!"
89
+ warn "#{@klass.name}: The aasm event name #{name} is already used!"
90
90
  end
91
91
 
92
92
  # an addition over standard aasm so that, before firing an event, you can ask
@@ -109,6 +109,10 @@ module AASM
109
109
  EORUBY
110
110
  end
111
111
 
112
+ def after_all_transitions(*callbacks, &block)
113
+ @state_machine.add_global_callbacks(:after_all_transitions, *callbacks, &block)
114
+ end
115
+
112
116
  def states
113
117
  @state_machine.states
114
118
  end
@@ -30,6 +30,7 @@ module AASM::Core
30
30
  end
31
31
 
32
32
  def execute(obj, *args)
33
+ invoke_callbacks_compatible_with_guard(event.state_machine.global_callbacks[:after_all_transitions], obj, args)
33
34
  invoke_callbacks_compatible_with_guard(@after, obj, args)
34
35
  end
35
36
 
@@ -49,6 +49,9 @@ module AASM
49
49
  state = options[:state] || current_state
50
50
  events = @instance.class.aasm(@name).events.select {|e| e.transitions_from_state?(state) }
51
51
 
52
+ options[:reject] = Array(options[:reject])
53
+ events.reject! { |e| options[:reject].include?(e.name) }
54
+
52
55
  if options[:permitted]
53
56
  # filters the results of events_for_current_state so that only those that
54
57
  # are really currently possible (given transition guards) are shown.
@@ -59,7 +62,7 @@ module AASM
59
62
  end
60
63
 
61
64
  def state_object_for_name(name)
62
- obj = @instance.class.aasm(@name).states.find {|s| s == name}
65
+ obj = @instance.class.aasm(@name).states.find {|s| s.name == name}
63
66
  raise AASM::UndefinedState, "State :#{name} doesn't exist" if obj.nil?
64
67
  obj
65
68
  end
@@ -56,8 +56,8 @@ module AASM
56
56
  def state_with_scope(name, *args)
57
57
  state_without_scope(name, *args)
58
58
  if @state_machine.config.create_scopes && !@klass.respond_to?(name)
59
- if @klass.ancestors.map {|klass| klass.to_s}.include?("ActiveRecord::Base")
60
59
 
60
+ if @klass.ancestors.map {|klass| klass.to_s}.include?("ActiveRecord::Base")
61
61
  conditions = {"#{@klass.table_name}.#{@klass.aasm(@name).attribute_name}" => name.to_s}
62
62
  if ActiveRecord::VERSION::MAJOR >= 3
63
63
  @klass.class_eval do
@@ -69,12 +69,17 @@ module AASM
69
69
  end
70
70
  end
71
71
  elsif @klass.ancestors.map {|klass| klass.to_s}.include?("Mongoid::Document")
72
- scope_options = lambda { @klass.send(:where, {@klass.aasm(@name).attribute_name.to_sym => name.to_s}) }
72
+ klass = @klass
73
+ state_machine_name = @name
74
+ scope_options = lambda {
75
+ klass.send(:where, {klass.aasm(state_machine_name).attribute_name.to_sym => name.to_s})
76
+ }
73
77
  @klass.send(:scope, name, scope_options)
74
78
  elsif @klass.ancestors.map {|klass| klass.to_s}.include?("MongoMapper::Document")
75
79
  conditions = { @klass.aasm(@name).attribute_name.to_sym => name.to_s }
76
80
  @klass.scope(name, lambda { @klass.where(conditions) })
77
81
  end
82
+
78
83
  end
79
84
  end
80
85
  alias_method :state_without_scope, :state
@@ -0,0 +1,22 @@
1
+ RSpec::Matchers.define :allow_event do |event|
2
+ match do |obj|
3
+ @state_machine_name ||= :default
4
+ obj.aasm(@state_machine_name).may_fire_event?(event)
5
+ end
6
+
7
+ chain :on do |state_machine_name|
8
+ @state_machine_name = state_machine_name
9
+ end
10
+
11
+ description do
12
+ "allow event #{expected} (on :#{@state_machine_name})"
13
+ end
14
+
15
+ failure_message do |obj|
16
+ "expected that the event :#{expected} would be allowed (on :#{@state_machine_name})"
17
+ end
18
+
19
+ failure_message_when_negated do |obj|
20
+ "expected that the event :#{expected} would not be allowed (on :#{@state_machine_name})"
21
+ end
22
+ end
@@ -0,0 +1,22 @@
1
+ RSpec::Matchers.define :allow_transition_to do |state|
2
+ match do |obj|
3
+ @state_machine_name ||= :default
4
+ obj.aasm(@state_machine_name).states(:permitted => true).include?(state)
5
+ end
6
+
7
+ chain :on do |state_machine_name|
8
+ @state_machine_name = state_machine_name
9
+ end
10
+
11
+ description do
12
+ "allow transition to #{expected} (on :#{@state_machine_name})"
13
+ end
14
+
15
+ failure_message do |obj|
16
+ "expected that the state :#{expected} would be reachable (on :#{@state_machine_name})"
17
+ end
18
+
19
+ failure_message_when_negated do |obj|
20
+ "expected that the state :#{expected} would not be reachable (on :#{@state_machine_name})"
21
+ end
22
+ end
@@ -0,0 +1,22 @@
1
+ RSpec::Matchers.define :have_state do |state|
2
+ match do |obj|
3
+ @state_machine_name ||= :default
4
+ obj.aasm(@state_machine_name).current_state == state.to_sym
5
+ end
6
+
7
+ chain :on do |state_machine_name|
8
+ @state_machine_name = state_machine_name
9
+ end
10
+
11
+ description do
12
+ "have state #{expected} (on :#{@state_machine_name})"
13
+ end
14
+
15
+ failure_message do |obj|
16
+ "expected that :#{obj.aasm(@state_machine_name).current_state} would be :#{expected} (on :#{@state_machine_name})"
17
+ end
18
+
19
+ failure_message_when_negated do |obj|
20
+ "expected that :#{obj.aasm(@state_machine_name).current_state} would not be :#{expected} (on :#{@state_machine_name})"
21
+ end
22
+ end
@@ -0,0 +1,32 @@
1
+ RSpec::Matchers.define :transition_from do |from_state|
2
+ match do |obj|
3
+ @state_machine_name ||= :default
4
+ obj.aasm(@state_machine_name).current_state = from_state.to_sym
5
+ # expect(obj).to receive(:broadcast_event).with(@event.to_s, obj, from_state, @to_state)
6
+ obj.send(@event) && obj.aasm(@state_machine_name).current_state == @to_state.to_sym
7
+ end
8
+
9
+ chain :on do |state_machine_name|
10
+ @state_machine_name = state_machine_name
11
+ end
12
+
13
+ chain :to do |state|
14
+ @to_state = state
15
+ end
16
+
17
+ chain :on_event do |event|
18
+ @event = event
19
+ end
20
+
21
+ description do
22
+ "transition state to :#{@to_state} from :#{expected} on event :#{@event} (on :#{@state_machine_name})"
23
+ end
24
+
25
+ failure_message do |obj|
26
+ "expected that :#{obj.aasm(@state_machine_name).current_state} would be :#{@to_state} (on :#{@state_machine_name})"
27
+ end
28
+
29
+ failure_message_when_negated do |obj|
30
+ "expected that :#{obj.aasm(@state_machine_name).current_state} would not be :#{@to_state} (on :#{@state_machine_name})"
31
+ end
32
+ end
data/lib/aasm/rspec.rb ADDED
@@ -0,0 +1,5 @@
1
+ # relative-require all rspec files
2
+ Dir[File.dirname(__FILE__) + '/rspec/*.rb'].each do |file|
3
+ require 'aasm/rspec/' + File.basename(file, File.extname(file))
4
+ end
5
+
@@ -10,12 +10,13 @@ module AASM
10
10
  (@machines ||= {})[klass.to_s] = machine
11
11
  end
12
12
 
13
- attr_accessor :states, :events, :initial_state, :config, :name
13
+ attr_accessor :states, :events, :initial_state, :config, :name, :global_callbacks
14
14
 
15
15
  def initialize(name)
16
16
  @initial_state = nil
17
17
  @states = []
18
18
  @events = {}
19
+ @global_callbacks = {}
19
20
  @config = AASM::Configuration.new
20
21
  @name = name
21
22
  end
@@ -40,6 +41,14 @@ module AASM
40
41
  @events[name] = AASM::Core::Event.new(name, self, options, &block)
41
42
  end
42
43
 
44
+ def add_global_callbacks(name, *callbacks, &block)
45
+ @global_callbacks[name] ||= []
46
+ callbacks.each do |callback|
47
+ @global_callbacks[name] << callback
48
+ end
49
+ @global_callbacks[name] << block if block
50
+ end
51
+
43
52
  private
44
53
 
45
54
  def set_initial_state(name, options)
data/lib/aasm/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module AASM
2
- VERSION = "4.3.0"
2
+ VERSION = "4.5.0"
3
3
  end
data/spec/database.rb CHANGED
@@ -1,5 +1,5 @@
1
1
  ActiveRecord::Migration.suppress_messages do
2
- %w{gates multiple_gates readers writers transients simples no_scopes multiple_no_scopes no_direct_assignments multiple_no_direct_assignments thieves multiple_thieves localizer_test_models persisted_states provided_and_persisted_states with_enums with_true_enums with_false_enums false_states multiple_with_enums multiple_with_true_enums multiple_with_false_enums multiple_false_states}.each do |table_name|
2
+ %w{gates multiple_gates readers writers transients simples no_scopes multiple_no_scopes no_direct_assignments multiple_no_direct_assignments thieves multiple_thieves localizer_test_models persisted_states provided_and_persisted_states with_enums with_true_enums with_false_enums false_states multiple_with_enums multiple_with_true_enums multiple_with_false_enums multiple_false_states readme_jobs}.each do |table_name|
3
3
  ActiveRecord::Migration.create_table table_name, :force => true do |t|
4
4
  t.string "aasm_state"
5
5
  end
@@ -0,0 +1,21 @@
1
+ class ReadmeJob < ActiveRecord::Base
2
+ include AASM
3
+
4
+ aasm do
5
+ state :sleeping, :initial => true
6
+ state :running
7
+ state :cleaning
8
+
9
+ event :run do
10
+ transitions :from => :sleeping, :to => :running
11
+ end
12
+
13
+ event :clean do
14
+ transitions :from => :running, :to => :cleaning
15
+ end
16
+
17
+ event :sleep do
18
+ transitions :from => [:running, :cleaning], :to => :sleeping
19
+ end
20
+ end
21
+ end
@@ -18,6 +18,8 @@ module Callbacks
18
18
  end
19
19
 
20
20
  aasm do
21
+ after_all_transitions :after_all_transitions
22
+
21
23
  state :open, :initial => true,
22
24
  :before_enter => :before_enter_open,
23
25
  :enter => :enter_open,
@@ -68,6 +70,7 @@ module Callbacks
68
70
  def transition_guard; log('transition_guard'); !@fail_transition_guard; end
69
71
 
70
72
  def after_transition; log('after_transition'); end
73
+ def after_all_transitions;log('after_all_transitions');end
71
74
 
72
75
  def before_event; log('before_event'); end
73
76
  def after_event; log('after_event'); end
@@ -4,7 +4,7 @@ module Callbacks
4
4
  include AASM
5
5
 
6
6
  aasm do
7
- state :open, :inital => true
7
+ state :open, :initial => true
8
8
  state :closed
9
9
  state :out_to_lunch
10
10
 
@@ -4,7 +4,7 @@ module Callbacks
4
4
  include AASM
5
5
 
6
6
  aasm(:left) do
7
- state :open, :inital => true
7
+ state :open, :initial => true
8
8
  state :closed
9
9
  state :out_to_lunch
10
10
 
data/spec/spec_helper.rb CHANGED
@@ -2,6 +2,7 @@ $LOAD_PATH.unshift(File.expand_path(File.dirname(__FILE__)))
2
2
  $LOAD_PATH.unshift(File.expand_path(File.join(File.dirname(__FILE__), '..', 'lib')))
3
3
  require 'aasm'
4
4
  require 'rspec'
5
+ require 'aasm/rspec'
5
6
 
6
7
  # require 'ruby-debug'; Debugger.settings[:autoeval] = true; debugger; rubys_debugger = 'annoying'
7
8
  # require 'ruby-debug/completion'
@@ -17,6 +17,7 @@ describe 'callbacks for the new DSL' do
17
17
  expect(callback).to receive(:exit_open).once.ordered
18
18
  # expect(callback).to receive(:event_guard).once.ordered.and_return(true)
19
19
  # expect(callback).to receive(:transition_guard).once.ordered.and_return(true)
20
+ expect(callback).to receive(:after_all_transitions).once.ordered
20
21
  expect(callback).to receive(:after_transition).once.ordered
21
22
  expect(callback).to receive(:before_enter_closed).once.ordered
22
23
  expect(callback).to receive(:enter_closed).once.ordered
@@ -103,4 +103,9 @@ describe 'permitted events' do
103
103
  expect(foo.aasm.events(:permitted => true)).to include(:close)
104
104
  expect(foo.aasm.events(:permitted => true)).not_to include(:null)
105
105
  end
106
+
107
+ it 'should not include events in the reject option' do
108
+ expect(foo.aasm.events(:permitted => true, reject: :close)).not_to include(:close)
109
+ expect(foo.aasm.events(:permitted => true, reject: [:close])).not_to include(:close)
110
+ end
106
111
  end
@@ -521,3 +521,20 @@ describe 'basic example with two state machines' do
521
521
  expect(example.aasm(:sync).current_state).to eql :unsynced
522
522
  end
523
523
  end
524
+
525
+ describe 'testing the README examples' do
526
+ it 'Usage' do
527
+ job = ReadmeJob.new
528
+
529
+ expect(job.sleeping?).to eql true
530
+ expect(job.may_run?).to eql true
531
+
532
+ job.run
533
+
534
+ expect(job.running?).to eql true
535
+ expect(job.sleeping?).to eql false
536
+ expect(job.may_run?).to eql false
537
+
538
+ expect { job.run }.to raise_error(AASM::InvalidTransition)
539
+ end
540
+ end
@@ -0,0 +1,42 @@
1
+ require 'spec_helper'
2
+
3
+ describe 'testing the README examples' do
4
+
5
+ it 'Usage' do
6
+ class Job
7
+ include AASM
8
+
9
+ aasm do
10
+ state :sleeping, :initial => true
11
+ state :running
12
+ state :cleaning
13
+
14
+ event :run do
15
+ transitions :from => :sleeping, :to => :running
16
+ end
17
+
18
+ event :clean do
19
+ transitions :from => :running, :to => :cleaning
20
+ end
21
+
22
+ event :sleep do
23
+ transitions :from => [:running, :cleaning], :to => :sleeping
24
+ end
25
+ end
26
+ end
27
+
28
+ job = Job.new
29
+
30
+ expect(job.sleeping?).to eql true
31
+ expect(job.may_run?).to eql true
32
+
33
+ job.run
34
+
35
+ expect(job.running?).to eql true
36
+ expect(job.sleeping?).to eql false
37
+ expect(job.may_run?).to eql false
38
+
39
+ expect { job.run }.to raise_error(AASM::InvalidTransition)
40
+ end
41
+
42
+ end
@@ -0,0 +1,79 @@
1
+ require 'spec_helper'
2
+
3
+ describe 'state machine' do
4
+ let(:simple) { SimpleExample.new }
5
+ let(:multiple) { SimpleMultipleExample.new }
6
+
7
+ describe 'transition_from' do
8
+ it "works for simple state machines" do
9
+ expect(simple).to transition_from(:initialised).to(:filled_out).on_event(:fill_out)
10
+ expect(simple).to_not transition_from(:initialised).to(:authorised).on_event(:fill_out)
11
+ end
12
+
13
+ it "works for multiple state machines" do
14
+ expect(multiple).to transition_from(:standing).to(:walking).on_event(:walk).on(:move)
15
+ expect(multiple).to_not transition_from(:standing).to(:running).on_event(:walk).on(:move)
16
+
17
+ expect(multiple).to transition_from(:sleeping).to(:processing).on_event(:start).on(:work)
18
+ expect(multiple).to_not transition_from(:sleeping).to(:sleeping).on_event(:start).on(:work)
19
+ end
20
+ end
21
+
22
+ describe 'allow_transition_to' do
23
+ it "works for simple state machines" do
24
+ expect(simple).to allow_transition_to(:filled_out)
25
+ expect(simple).to_not allow_transition_to(:authorised)
26
+ end
27
+
28
+ it "works for multiple state machines" do
29
+ expect(multiple).to allow_transition_to(:walking).on(:move)
30
+ expect(multiple).to_not allow_transition_to(:standing).on(:move)
31
+
32
+ expect(multiple).to allow_transition_to(:processing).on(:work)
33
+ expect(multiple).to_not allow_transition_to(:sleeping).on(:work)
34
+ end
35
+ end
36
+
37
+ describe "have_state" do
38
+ it "works for simple state machines" do
39
+ expect(simple).to have_state :initialised
40
+ expect(simple).to_not have_state :filled_out
41
+ simple.fill_out
42
+ expect(simple).to have_state :filled_out
43
+ end
44
+
45
+ it "works for multiple state machines" do
46
+ expect(multiple).to have_state(:standing).on(:move)
47
+ expect(multiple).to_not have_state(:walking).on(:move)
48
+ multiple.walk
49
+ expect(multiple).to have_state(:walking).on(:move)
50
+
51
+ expect(multiple).to have_state(:sleeping).on(:work)
52
+ expect(multiple).to_not have_state(:processing).on(:work)
53
+ multiple.start
54
+ expect(multiple).to have_state(:processing).on(:work)
55
+ end
56
+ end
57
+
58
+ describe "allow_event" do
59
+ it "works for simple state machines" do
60
+ expect(simple).to allow_event :fill_out
61
+ expect(simple).to_not allow_event :authorise
62
+ simple.fill_out
63
+ expect(simple).to allow_event :authorise
64
+ end
65
+
66
+ it "works for multiple state machines" do
67
+ expect(multiple).to allow_event(:walk).on(:move)
68
+ expect(multiple).to_not allow_event(:hold).on(:move)
69
+ multiple.walk
70
+ expect(multiple).to allow_event(:hold).on(:move)
71
+
72
+ expect(multiple).to allow_event(:start).on(:work)
73
+ expect(multiple).to_not allow_event(:stop).on(:work)
74
+ multiple.start
75
+ expect(multiple).to allow_event(:stop).on(:work)
76
+ end
77
+ end
78
+
79
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: aasm
3
3
  version: !ruby/object:Gem::Version
4
- version: 4.3.0
4
+ version: 4.5.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Scott Barron
@@ -10,7 +10,7 @@ authors:
10
10
  autorequire:
11
11
  bindir: bin
12
12
  cert_chain: []
13
- date: 2015-09-10 00:00:00.000000000 Z
13
+ date: 2015-11-16 00:00:00.000000000 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: rake
@@ -92,11 +92,12 @@ files:
92
92
  - callbacks.txt
93
93
  - gemfiles/rails_3.2.gemfile
94
94
  - gemfiles/rails_4.0.gemfile
95
- - gemfiles/rails_4.0_bson1.gemfile
95
+ - gemfiles/rails_4.0_mongo_mapper.gemfile
96
96
  - gemfiles/rails_4.1.gemfile
97
- - gemfiles/rails_4.1_bson1.gemfile
97
+ - gemfiles/rails_4.1_mongo_mapper.gemfile
98
98
  - gemfiles/rails_4.2.gemfile
99
- - gemfiles/rails_4.2_bson1.gemfile
99
+ - gemfiles/rails_4.2_mongo_mapper.gemfile
100
+ - gemfiles/rails_4.2_mongoid_5.gemfile
100
101
  - lib/aasm.rb
101
102
  - lib/aasm/aasm.rb
102
103
  - lib/aasm/base.rb
@@ -115,6 +116,11 @@ files:
115
116
  - lib/aasm/persistence/mongoid_persistence.rb
116
117
  - lib/aasm/persistence/plain_persistence.rb
117
118
  - lib/aasm/persistence/sequel_persistence.rb
119
+ - lib/aasm/rspec.rb
120
+ - lib/aasm/rspec/allow_event.rb
121
+ - lib/aasm/rspec/allow_transition_to.rb
122
+ - lib/aasm/rspec/have_state.rb
123
+ - lib/aasm/rspec/transition_from.rb
118
124
  - lib/aasm/state_machine.rb
119
125
  - lib/aasm/version.rb
120
126
  - spec/database.rb
@@ -132,6 +138,7 @@ files:
132
138
  - spec/models/active_record/persisted_state.rb
133
139
  - spec/models/active_record/provided_and_persisted_state.rb
134
140
  - spec/models/active_record/reader.rb
141
+ - spec/models/active_record/readme_job.rb
135
142
  - spec/models/active_record/simple_new_dsl.rb
136
143
  - spec/models/active_record/thief.rb
137
144
  - spec/models/active_record/transient.rb
@@ -220,7 +227,9 @@ files:
220
227
  - spec/unit/persistence/mongoid_persistence_spec.rb
221
228
  - spec/unit/persistence/sequel_persistence_multiple_spec.rb
222
229
  - spec/unit/persistence/sequel_persistence_spec.rb
230
+ - spec/unit/readme_spec.rb
223
231
  - spec/unit/reloading_spec.rb
232
+ - spec/unit/rspec_matcher_spec.rb
224
233
  - spec/unit/simple_example_spec.rb
225
234
  - spec/unit/simple_multiple_example_spec.rb
226
235
  - spec/unit/state_spec.rb
@@ -267,6 +276,7 @@ test_files:
267
276
  - spec/models/active_record/persisted_state.rb
268
277
  - spec/models/active_record/provided_and_persisted_state.rb
269
278
  - spec/models/active_record/reader.rb
279
+ - spec/models/active_record/readme_job.rb
270
280
  - spec/models/active_record/simple_new_dsl.rb
271
281
  - spec/models/active_record/thief.rb
272
282
  - spec/models/active_record/transient.rb
@@ -355,7 +365,9 @@ test_files:
355
365
  - spec/unit/persistence/mongoid_persistence_spec.rb
356
366
  - spec/unit/persistence/sequel_persistence_multiple_spec.rb
357
367
  - spec/unit/persistence/sequel_persistence_spec.rb
368
+ - spec/unit/readme_spec.rb
358
369
  - spec/unit/reloading_spec.rb
370
+ - spec/unit/rspec_matcher_spec.rb
359
371
  - spec/unit/simple_example_spec.rb
360
372
  - spec/unit/simple_multiple_example_spec.rb
361
373
  - spec/unit/state_spec.rb