aasm 2.3.1 → 2.4.0

Sign up to get free protection for your applications and to get access to all the features.
data/.gitignore CHANGED
@@ -9,3 +9,4 @@ Gemfile.lock
9
9
  spec/debug.log
10
10
  spec/*.db
11
11
  TODO
12
+ .rvmrc
@@ -0,0 +1,15 @@
1
+ # CHANGELOG
2
+
3
+ ## 2.4.0
4
+
5
+ * supporting new DSL (which is much shorter)
6
+
7
+ ## 2.3.1
8
+
9
+ * bugfix: avoid naming conflict with i18n
10
+
11
+ ## 2.3.0
12
+
13
+ * supporting i18n
14
+ * supporting regular expressions for hash values and strings
15
+
data/LICENSE CHANGED
@@ -1,4 +1,4 @@
1
- Copyright (c) 2008 Scott Barron
1
+ Copyright (c) 2008-2011 Scott Barron
2
2
 
3
3
  Permission is hereby granted, free of charge, to any person obtaining
4
4
  a copy of this software and associated documentation files (the
data/README.md CHANGED
@@ -32,21 +32,21 @@ The callback chain & order on a successful event looks like:
32
32
  (*) marks old callbacks
33
33
 
34
34
 
35
- ## Download ##
36
-
37
- The latest AASM can currently be pulled from the git repository on github.
38
-
39
- * http://github.com/rubyist/aasm/tree/master
40
-
41
-
42
35
  ## Installation ##
43
36
 
44
- ### From RubyGems.org ###
37
+ ### Manually from RubyGems.org ###
45
38
 
46
39
  ```sh
47
40
  % gem install aasm
48
41
  ```
49
42
 
43
+ ### Or if you are using Bundler ###
44
+
45
+ ```ruby
46
+ # Gemfile
47
+ gem 'aasm'
48
+ ```
49
+
50
50
  ### Building your own gems ###
51
51
 
52
52
  ```sh
@@ -133,13 +133,17 @@ This example uses a few of the more complex features available.
133
133
  end
134
134
  ```
135
135
 
136
+ ## Changelog ##
136
137
 
137
- # Other Stuff #
138
+ Look at the [CHANGELOG](https://github.com/rubyist/aasm/blob/master/CHANGELOG.md) for details.
139
+
140
+
141
+ ## Authors ##
142
+
143
+ * [Scott Barron](https://github.com/rubyist)
144
+ * [Travis Tilley](https://github.com/ttilley)
145
+ * [Thorsten Böttger](http://github.com/alto),
138
146
 
139
- Author:: Scott Barron <scott at elitists dot net>
140
- License:: Original code Copyright 2006, 2007, 2008 by Scott Barron.
141
- Released under an MIT-style license. See the LICENSE file
142
- included in the distribution.
143
147
 
144
148
  ## Warranty ##
145
149
 
@@ -147,3 +151,26 @@ This software is provided "as is" and without any express or
147
151
  implied warranties, including, without limitation, the implied
148
152
  warranties of merchantibility and fitness for a particular
149
153
  purpose.
154
+
155
+ ## License ##
156
+
157
+ Copyright (c) 2006-2011 Scott Barron
158
+
159
+ Permission is hereby granted, free of charge, to any person obtaining
160
+ a copy of this software and associated documentation files (the
161
+ "Software"), to deal in the Software without restriction, including
162
+ without limitation the rights to use, copy, modify, merge, publish,
163
+ distribute, sublicense, and/or sell copies of the Software, and to
164
+ permit persons to whom the Software is furnished to do so, subject to
165
+ the following conditions:
166
+
167
+ The above copyright notice and this permission notice shall be
168
+ included in all copies or substantial portions of the Software.
169
+
170
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
171
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
172
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
173
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
174
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
175
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
176
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/Rakefile CHANGED
@@ -13,8 +13,6 @@ Rake::TestTask.new(:test) do |test|
13
13
  test.verbose = true
14
14
  end
15
15
 
16
- task :default => :test
17
-
18
16
  require 'rdoc/task'
19
17
  require 'aasm/version'
20
18
  require 'sdoc'
@@ -25,3 +23,5 @@ Rake::RDocTask.new do |rdoc|
25
23
  rdoc.rdoc_files.include('README*')
26
24
  rdoc.rdoc_files.include('lib/**/*.rb')
27
25
  end
26
+
27
+ task :default => :spec
@@ -21,61 +21,49 @@ module AASM
21
21
  super
22
22
  end
23
23
 
24
+ def aasm(options={}, &block)
25
+ @aasm ||= AASM::Base.new(self, options)
26
+ @aasm.instance_eval(&block) if block
27
+ @aasm
28
+ end
29
+
24
30
  def aasm_initial_state(set_state=nil)
25
31
  if set_state
32
+ # deprecated
26
33
  AASM::StateMachine[self].initial_state = set_state
27
34
  else
28
35
  AASM::StateMachine[self].initial_state
29
36
  end
30
37
  end
31
38
 
39
+ # deprecated
32
40
  def aasm_initial_state=(state)
33
41
  AASM::StateMachine[self].initial_state = state
34
42
  end
35
43
 
44
+ # deprecated
36
45
  def aasm_state(name, options={})
37
- sm = AASM::StateMachine[self]
38
- sm.create_state(name, options)
39
- sm.initial_state = name unless sm.initial_state
40
-
41
- define_method("#{name.to_s}?") do
42
- aasm_current_state == name
43
- end
46
+ aasm.state(name, options)
44
47
  end
45
48
 
49
+ # deprecated
46
50
  def aasm_event(name, options = {}, &block)
47
- sm = AASM::StateMachine[self]
48
-
49
- unless sm.events.has_key?(name)
50
- sm.events[name] = AASM::SupportingClasses::Event.new(name, options, &block)
51
- end
52
-
53
- # an addition over standard aasm so that, before firing an event, you can ask
54
- # may_event? and get back a boolean that tells you whether the guard method
55
- # on the transition will let this happen.
56
- define_method("may_#{name.to_s}?") do |*args|
57
- aasm_test_event(name, *args)
58
- end
59
-
60
- define_method("#{name.to_s}!") do |*args|
61
- aasm_fire_event(name, true, *args)
62
- end
63
-
64
- define_method("#{name.to_s}") do |*args|
65
- aasm_fire_event(name, false, *args)
66
- end
51
+ aasm.event(name, options, &block)
67
52
  end
68
53
 
54
+ # deprecated
69
55
  def aasm_states
70
- AASM::StateMachine[self].states
56
+ aasm.states
71
57
  end
72
58
 
59
+ # deprecated
73
60
  def aasm_events
74
- AASM::StateMachine[self].events
61
+ aasm.events
75
62
  end
76
63
 
64
+ # deprecated
77
65
  def aasm_states_for_select
78
- AASM::StateMachine[self].states.map { |state| state.for_select }
66
+ aasm.states_for_select
79
67
  end
80
68
 
81
69
  def human_event_name(event)
@@ -126,7 +114,7 @@ module AASM
126
114
  AASM::Localizer.new.human_state(self)
127
115
  end
128
116
 
129
- private
117
+ private
130
118
 
131
119
  def set_aasm_current_state_with_persistence(state)
132
120
  save_success = true
@@ -0,0 +1,56 @@
1
+ module AASM
2
+ class Base
3
+ def initialize(clazz, options={}, &block)
4
+ @clazz = clazz
5
+ sm = AASM::StateMachine[@clazz]
6
+ sm.config.column = options[:column].to_sym if options[:column]
7
+ end
8
+
9
+ def state(name, options={})
10
+ # @clazz.aasm_state(name, options)
11
+ sm = AASM::StateMachine[@clazz]
12
+ sm.create_state(name, options)
13
+ sm.initial_state = name if options[:initial] || !sm.initial_state
14
+
15
+ @clazz.send(:define_method, "#{name.to_s}?") do
16
+ aasm_current_state == name
17
+ end
18
+ end
19
+
20
+ def event(name, options={}, &block)
21
+ # @clazz.aasm_event(name, options, &block)
22
+ sm = AASM::StateMachine[@clazz]
23
+
24
+ unless sm.events.has_key?(name)
25
+ sm.events[name] = AASM::SupportingClasses::Event.new(name, options, &block)
26
+ end
27
+
28
+ # an addition over standard aasm so that, before firing an event, you can ask
29
+ # may_event? and get back a boolean that tells you whether the guard method
30
+ # on the transition will let this happen.
31
+ @clazz.send(:define_method, "may_#{name.to_s}?") do |*args|
32
+ aasm_test_event(name, *args)
33
+ end
34
+
35
+ @clazz.send(:define_method, "#{name.to_s}!") do |*args|
36
+ aasm_fire_event(name, true, *args)
37
+ end
38
+
39
+ @clazz.send(:define_method, "#{name.to_s}") do |*args|
40
+ aasm_fire_event(name, false, *args)
41
+ end
42
+ end
43
+
44
+ def states
45
+ AASM::StateMachine[@clazz].states
46
+ end
47
+
48
+ def events
49
+ AASM::StateMachine[@clazz].events
50
+ end
51
+
52
+ def states_for_select
53
+ states.map { |state| state.for_select }
54
+ end
55
+ end
56
+ end
@@ -1,6 +1,7 @@
1
1
  module AASM::SupportingClasses
2
2
  end
3
3
 
4
+ require File.join(File.dirname(__FILE__), 'base')
4
5
  require File.join(File.dirname(__FILE__), 'state_transition')
5
6
  require File.join(File.dirname(__FILE__), 'event')
6
7
  require File.join(File.dirname(__FILE__), 'state')
@@ -1,3 +1,3 @@
1
1
  module AASM
2
- VERSION = "2.3.1"
2
+ VERSION = "2.4.0"
3
3
  end
@@ -1,5 +1,3 @@
1
- require File.join(File.dirname(__FILE__), '..', '..', 'lib', 'aasm')
2
-
3
1
  class Conversation
4
2
  include AASM
5
3
 
@@ -0,0 +1,31 @@
1
+ class ProcessWithNewDsl
2
+ include AASM
3
+
4
+ def self.state(*args)
5
+ raise "wrong state method"
6
+ end
7
+
8
+ attr_accessor :flagged
9
+
10
+ aasm do
11
+ state :sleeping, :initial => true
12
+ state :running, :after_enter => :flag
13
+ state :suspended
14
+
15
+ event :start do
16
+ transitions :from => :sleeping, :to => :running
17
+ end
18
+ event :stop do
19
+ transitions :from => :running, :to => :suspended
20
+ end
21
+ end
22
+
23
+ def flag
24
+ self.flagged = true
25
+ end
26
+
27
+ def self.event(*args)
28
+ raise "wrong event method"
29
+ end
30
+
31
+ end
@@ -14,3 +14,6 @@ def load_schema
14
14
  ActiveRecord::Base.establish_connection(config['sqlite3'])
15
15
  load(File.dirname(__FILE__) + "/schema.rb")
16
16
  end
17
+
18
+ # Requiring custom spec helpers
19
+ Dir[File.dirname(__FILE__) + "/spec_helpers/**/*.rb"].sort.each { |f| require File.expand_path(f) }
@@ -0,0 +1,184 @@
1
+ Dir[File.dirname(__FILE__) + "/../models/*.rb"].each { |f| require File.expand_path(f) }
2
+
3
+ class Foo
4
+ include AASM
5
+ aasm_initial_state :open
6
+ aasm_state :open, :exit => :exit
7
+ aasm_state :closed, :enter => :enter
8
+
9
+ aasm_event :close, :success => :success_callback do
10
+ transitions :to => :closed, :from => [:open]
11
+ end
12
+
13
+ aasm_event :null do
14
+ transitions :to => :closed, :from => [:open], :guard => :always_false
15
+ end
16
+
17
+ def always_false
18
+ false
19
+ end
20
+
21
+ def success_callback
22
+ end
23
+
24
+ def enter
25
+ end
26
+ def exit
27
+ end
28
+ end
29
+
30
+ class FooTwo < Foo
31
+ include AASM
32
+ aasm_state :foo
33
+ end
34
+
35
+ class Bar
36
+ include AASM
37
+
38
+ aasm_state :read
39
+ aasm_state :ended
40
+
41
+ aasm_event :foo do
42
+ transitions :to => :ended, :from => [:read]
43
+ end
44
+ end
45
+
46
+ class Baz < Bar
47
+ end
48
+
49
+ class Banker
50
+ include AASM
51
+ aasm_initial_state Proc.new { |banker| banker.rich? ? :retired : :selling_bad_mortgages }
52
+ aasm_state :retired
53
+ aasm_state :selling_bad_mortgages
54
+ RICH = 1_000_000
55
+ attr_accessor :balance
56
+ def initialize(balance = 0); self.balance = balance; end
57
+ def rich?; self.balance >= RICH; end
58
+ end
59
+
60
+ class Argument
61
+ include AASM
62
+ aasm_initial_state :invalid
63
+ aasm_state :invalid
64
+ aasm_state :valid
65
+
66
+ aasm_event :valid do
67
+ transitions :to => :valid, :from => [:invalid]
68
+ end
69
+ end
70
+
71
+ class AuthMachine
72
+ include AASM
73
+
74
+ attr_accessor :activation_code, :activated_at, :deleted_at
75
+
76
+ aasm_initial_state :pending
77
+
78
+ aasm_state :passive
79
+ aasm_state :pending, :enter => :make_activation_code
80
+ aasm_state :active, :enter => :do_activate
81
+ aasm_state :suspended
82
+ aasm_state :deleted, :enter => :do_delete, :exit => :do_undelete
83
+
84
+ aasm_event :register do
85
+ transitions :from => :passive, :to => :pending, :guard => Proc.new {|u| u.can_register? }
86
+ end
87
+
88
+ aasm_event :activate do
89
+ transitions :from => :pending, :to => :active
90
+ end
91
+
92
+ aasm_event :suspend do
93
+ transitions :from => [:passive, :pending, :active], :to => :suspended
94
+ end
95
+
96
+ aasm_event :delete do
97
+ transitions :from => [:passive, :pending, :active, :suspended], :to => :deleted
98
+ end
99
+
100
+ # a dummy event that can never happen
101
+ aasm_event :unpassify do
102
+ transitions :from => :passive, :to => :active, :guard => Proc.new {|u| false }
103
+ end
104
+
105
+ aasm_event :unsuspend do
106
+ transitions :from => :suspended, :to => :active, :guard => Proc.new {|u| u.has_activated? }
107
+ transitions :from => :suspended, :to => :pending, :guard => Proc.new {|u| u.has_activation_code? }
108
+ transitions :from => :suspended, :to => :passive
109
+ end
110
+
111
+ def initialize
112
+ # the AR backend uses a before_validate_on_create :aasm_ensure_initial_state
113
+ # lets do something similar here for testing purposes.
114
+ aasm_enter_initial_state
115
+ end
116
+
117
+ def make_activation_code
118
+ @activation_code = 'moo'
119
+ end
120
+
121
+ def do_activate
122
+ @activated_at = Time.now
123
+ @activation_code = nil
124
+ end
125
+
126
+ def do_delete
127
+ @deleted_at = Time.now
128
+ end
129
+
130
+ def do_undelete
131
+ @deleted_at = false
132
+ end
133
+
134
+ def can_register?
135
+ true
136
+ end
137
+
138
+ def has_activated?
139
+ !!@activated_at
140
+ end
141
+
142
+ def has_activation_code?
143
+ !!@activation_code
144
+ end
145
+ end
146
+
147
+ class ThisNameBetterNotBeInUse
148
+ include AASM
149
+
150
+ aasm_state :initial
151
+ aasm_state :symbol
152
+ aasm_state :string
153
+ aasm_state :array
154
+ aasm_state :proc
155
+ end
156
+
157
+ class ChetanPatil
158
+ include AASM
159
+ aasm_initial_state :sleeping
160
+ aasm_state :sleeping
161
+ aasm_state :showering
162
+ aasm_state :working
163
+ aasm_state :dating
164
+ aasm_state :prettying_up
165
+
166
+ aasm_event :wakeup do
167
+ transitions :from => :sleeping, :to => [:showering, :working]
168
+ end
169
+
170
+ aasm_event :dress do
171
+ transitions :from => :sleeping, :to => :working, :on_transition => :wear_clothes
172
+ transitions :from => :showering, :to => [:working, :dating], :on_transition => Proc.new { |obj, *args| obj.wear_clothes(*args) }
173
+ transitions :from => :showering, :to => :prettying_up, :on_transition => [:condition_hair, :fix_hair]
174
+ end
175
+
176
+ def wear_clothes(shirt_color, trouser_type)
177
+ end
178
+
179
+ def condition_hair
180
+ end
181
+
182
+ def fix_hair
183
+ end
184
+ end