dm-is-persistent_state_machine 0.0.2 → 0.1.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.
- data/VERSION +1 -1
- data/dm-is-persistent_state_machine.gemspec +8 -6
- data/lib/dm-is-persistent_state_machine/is/persistent_state_machine.rb +41 -17
- data/spec/dm-is-persistent_state_machine_spec.rb +41 -0
- data/spec/rcov.opts +6 -0
- data/spec/spec.opts +4 -0
- data/spec/spec_helper.rb +24 -0
- metadata +8 -6
- data/test/helper.rb +0 -10
- data/test/test_dm-is-persistent_state_machine.rb +0 -7
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.0
|
1
|
+
0.1.0
|
@@ -5,11 +5,11 @@
|
|
5
5
|
|
6
6
|
Gem::Specification.new do |s|
|
7
7
|
s.name = %q{dm-is-persistent_state_machine}
|
8
|
-
s.version = "0.0
|
8
|
+
s.version = "0.1.0"
|
9
9
|
|
10
10
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
11
|
s.authors = ["michael"]
|
12
|
-
s.date = %q{2010-01-
|
12
|
+
s.date = %q{2010-01-14}
|
13
13
|
s.description = %q{A persistent State Machine for DataMapper}
|
14
14
|
s.email = %q{ma@zive.at}
|
15
15
|
s.extra_rdoc_files = [
|
@@ -26,8 +26,10 @@ Gem::Specification.new do |s|
|
|
26
26
|
"dm-is-persistent_state_machine.gemspec",
|
27
27
|
"lib/dm-is-persistent_state_machine.rb",
|
28
28
|
"lib/dm-is-persistent_state_machine/is/persistent_state_machine.rb",
|
29
|
-
"
|
30
|
-
"
|
29
|
+
"spec/dm-is-persistent_state_machine_spec.rb",
|
30
|
+
"spec/rcov.opts",
|
31
|
+
"spec/spec.opts",
|
32
|
+
"spec/spec_helper.rb"
|
31
33
|
]
|
32
34
|
s.homepage = %q{http://github.com/michael/dm-is-persistent_state_machine}
|
33
35
|
s.rdoc_options = ["--charset=UTF-8"]
|
@@ -35,8 +37,8 @@ Gem::Specification.new do |s|
|
|
35
37
|
s.rubygems_version = %q{1.3.5}
|
36
38
|
s.summary = %q{A persistent State Machine for DataMapper}
|
37
39
|
s.test_files = [
|
38
|
-
"
|
39
|
-
"
|
40
|
+
"spec/dm-is-persistent_state_machine_spec.rb",
|
41
|
+
"spec/spec_helper.rb"
|
40
42
|
]
|
41
43
|
|
42
44
|
if s.respond_to? :specification_version then
|
@@ -15,12 +15,12 @@ end
|
|
15
15
|
class State
|
16
16
|
include DataMapper::Resource
|
17
17
|
|
18
|
-
property :id,
|
19
|
-
property :code,
|
20
|
-
property :name,
|
21
|
-
property :editable,
|
22
|
-
property :sorter,
|
23
|
-
property :type,
|
18
|
+
property :id, Serial
|
19
|
+
property :code, String, :required => true, :unique => true, :unique_index => true
|
20
|
+
property :name, String, :required => true, :unique => true, :unique_index => true
|
21
|
+
property :editable, Boolean, :default => true
|
22
|
+
property :sorter, Integer
|
23
|
+
property :type, Discriminator
|
24
24
|
|
25
25
|
# outgoing transitions
|
26
26
|
has n, :state_transitions, 'StateTransition', :child_key => [:state_id]
|
@@ -51,12 +51,26 @@ end
|
|
51
51
|
class StateEvent
|
52
52
|
include DataMapper::Resource
|
53
53
|
|
54
|
-
property :id,
|
54
|
+
property :id, Serial
|
55
55
|
property :code, String, :required => true, :unique => true, :unique_index => true
|
56
56
|
property :name, String, :required => true, :unique => true, :unique_index => true
|
57
57
|
property :type, Discriminator
|
58
58
|
end
|
59
59
|
|
60
|
+
class StateChange
|
61
|
+
include DataMapper::Resource
|
62
|
+
|
63
|
+
property :id, Serial
|
64
|
+
|
65
|
+
property :from_id, Integer, :required => true, :min => 1, :unique_index => :type
|
66
|
+
property :to_id, Integer, :required => true, :min => 1, :unique_index => :type
|
67
|
+
|
68
|
+
property :created_at, DateTime
|
69
|
+
|
70
|
+
# associations
|
71
|
+
belongs_to :from, "State"
|
72
|
+
belongs_to :to, "State"
|
73
|
+
end
|
60
74
|
|
61
75
|
module DataMapper
|
62
76
|
module Is
|
@@ -79,7 +93,8 @@ module DataMapper
|
|
79
93
|
##
|
80
94
|
|
81
95
|
def is_persistent_state_machine
|
82
|
-
|
96
|
+
DataMapper.logger.info "registering persistent state machine..."
|
97
|
+
|
83
98
|
# Add class-methods
|
84
99
|
extend DataMapper::Is::PersistentStateMachine::ClassMethods
|
85
100
|
extend Forwardable
|
@@ -90,32 +105,41 @@ module DataMapper
|
|
90
105
|
property :state_id, Integer, :required => true, :min => 1
|
91
106
|
belongs_to :state
|
92
107
|
|
93
|
-
DataMapper.logger.info "registering persistent state machine..."
|
94
|
-
|
95
|
-
# define delegators
|
96
|
-
def_delegators :@state, :events
|
97
|
-
|
98
108
|
# generate a FooState class that is derived from State
|
99
109
|
state_model = Object.full_const_set(self.to_s+"State", Class.new(State))
|
100
110
|
# generate a FooStateEvent class that is derived from StateEvent
|
101
111
|
event_model = Object.full_const_set(self.to_s+"StateEvent", Class.new(StateEvent))
|
112
|
+
|
113
|
+
after :save do
|
114
|
+
if (@prev_state && @prev_state != state)
|
115
|
+
StateChange.create(:from => @prev_state, :to => state, :created_at => DateTime.now)
|
116
|
+
end
|
117
|
+
end
|
118
|
+
|
119
|
+
# define delegators
|
120
|
+
def_delegators :@state, :events
|
102
121
|
end
|
103
122
|
|
104
123
|
##
|
105
124
|
# fired after trigger_event! is called on resource
|
106
125
|
#
|
107
|
-
def after_trigger_event(event)
|
108
|
-
end
|
109
|
-
|
110
126
|
module ClassMethods
|
111
127
|
|
112
128
|
end # ClassMethods
|
113
129
|
|
114
130
|
module InstanceMethods
|
115
|
-
def trigger_event!(event_code)
|
131
|
+
def trigger_event!(event_code)
|
132
|
+
# cache the old value
|
133
|
+
@prev_state = self.state
|
134
|
+
|
116
135
|
# delegate to State#trigger!
|
117
136
|
self.state.trigger_event!(self, event_code)
|
118
137
|
end
|
138
|
+
|
139
|
+
# hookable
|
140
|
+
def after_trigger_event(event)
|
141
|
+
|
142
|
+
end
|
119
143
|
end # InstanceMethods
|
120
144
|
end # PersistentStateMachine
|
121
145
|
end # Is
|
@@ -0,0 +1,41 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe DataMapper::Is::PersistentStateMachine do
|
4
|
+
|
5
|
+
before(:all) do
|
6
|
+
DataMapper.auto_migrate!
|
7
|
+
|
8
|
+
# add some states
|
9
|
+
open = ProjectState.create(:name => "Open", :code => "open")
|
10
|
+
reviewed = ProjectState.create(:name => "Reviewed", :code => "reviewed")
|
11
|
+
confirmed = ProjectState.create(:name => "Confirmed", :code => "confirmed")
|
12
|
+
|
13
|
+
# add some events
|
14
|
+
review_evt = ProjectStateEvent.create(:code => "review", :name => "Review")
|
15
|
+
confirm_evt = ProjectStateEvent.create(:code => "confirm", :name => "Confirm")
|
16
|
+
|
17
|
+
# add some transitions
|
18
|
+
open_reviewed = StateTransition.create(:state => open, :target => reviewed, :state_event => review_evt)
|
19
|
+
reviewed_confirmed = StateTransition.create(:state => reviewed, :target => confirmed, :state_event => confirm_evt)
|
20
|
+
end
|
21
|
+
|
22
|
+
describe "with active DM Identity Map" do
|
23
|
+
|
24
|
+
before :each do
|
25
|
+
Project.auto_migrate!
|
26
|
+
StateChange.auto_migrate!
|
27
|
+
end
|
28
|
+
|
29
|
+
it "should log state changes" do
|
30
|
+
@project = Project.create(:name => "Operation X", :state => ProjectState.first(:code => "open"))
|
31
|
+
@project.state.code.should == "open"
|
32
|
+
@project.trigger_event!('review')
|
33
|
+
Project.first(:name => "Operation X").state.code.should == "open" # not persistent yet
|
34
|
+
|
35
|
+
StateChange.count.should == 0
|
36
|
+
@project.state.code.should == "reviewed"
|
37
|
+
@project.save
|
38
|
+
StateChange.count.should == 1
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
data/spec/rcov.opts
ADDED
data/spec/spec.opts
ADDED
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,24 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
|
3
|
+
require 'dm-core'
|
4
|
+
require 'dm-adjust'
|
5
|
+
require 'dm-aggregates'
|
6
|
+
require 'dm-types'
|
7
|
+
require 'dm-validations'
|
8
|
+
|
9
|
+
$LOAD_PATH.unshift File.expand_path('../lib', __FILE__)
|
10
|
+
|
11
|
+
require 'dm-is-persistent_state_machine'
|
12
|
+
|
13
|
+
DataMapper.setup(:default, 'sqlite3::memory:')
|
14
|
+
|
15
|
+
# classes/vars for tests
|
16
|
+
|
17
|
+
class Project
|
18
|
+
include DataMapper::Resource
|
19
|
+
|
20
|
+
property :id, Serial
|
21
|
+
property :name, String
|
22
|
+
|
23
|
+
is :persistent_state_machine
|
24
|
+
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: dm-is-persistent_state_machine
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0
|
4
|
+
version: 0.1.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- michael
|
@@ -9,7 +9,7 @@ autorequire:
|
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
11
|
|
12
|
-
date: 2010-01-
|
12
|
+
date: 2010-01-14 00:00:00 +01:00
|
13
13
|
default_executable:
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
@@ -41,8 +41,10 @@ files:
|
|
41
41
|
- dm-is-persistent_state_machine.gemspec
|
42
42
|
- lib/dm-is-persistent_state_machine.rb
|
43
43
|
- lib/dm-is-persistent_state_machine/is/persistent_state_machine.rb
|
44
|
-
-
|
45
|
-
-
|
44
|
+
- spec/dm-is-persistent_state_machine_spec.rb
|
45
|
+
- spec/rcov.opts
|
46
|
+
- spec/spec.opts
|
47
|
+
- spec/spec_helper.rb
|
46
48
|
has_rdoc: true
|
47
49
|
homepage: http://github.com/michael/dm-is-persistent_state_machine
|
48
50
|
licenses: []
|
@@ -72,5 +74,5 @@ signing_key:
|
|
72
74
|
specification_version: 3
|
73
75
|
summary: A persistent State Machine for DataMapper
|
74
76
|
test_files:
|
75
|
-
-
|
76
|
-
-
|
77
|
+
- spec/dm-is-persistent_state_machine_spec.rb
|
78
|
+
- spec/spec_helper.rb
|
data/test/helper.rb
DELETED