dm-is-persistent_state_machine 0.0.2 → 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.0.2
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.2"
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-04}
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
- "test/helper.rb",
30
- "test/test_dm-is-persistent_state_machine.rb"
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
- "test/helper.rb",
39
- "test/test_dm-is-persistent_state_machine.rb"
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, 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
22
- property :sorter, Integer
23
- property :type, Discriminator
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, Serial
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
@@ -0,0 +1,6 @@
1
+ --exclude "spec"
2
+ --sort coverage
3
+ --callsites
4
+ --xrefs
5
+ --profile
6
+ --text-summary
data/spec/spec.opts ADDED
@@ -0,0 +1,4 @@
1
+ --colour
2
+ --loadby random
3
+ --format specdoc
4
+ --backtrace
@@ -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.2
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-04 00:00:00 +01:00
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
- - test/helper.rb
45
- - test/test_dm-is-persistent_state_machine.rb
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
- - test/helper.rb
76
- - test/test_dm-is-persistent_state_machine.rb
77
+ - spec/dm-is-persistent_state_machine_spec.rb
78
+ - spec/spec_helper.rb
data/test/helper.rb DELETED
@@ -1,10 +0,0 @@
1
- require 'rubygems'
2
- require 'test/unit'
3
- require 'shoulda'
4
-
5
- $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
6
- $LOAD_PATH.unshift(File.dirname(__FILE__))
7
- require 'dm-is-persistent_state_machine'
8
-
9
- class Test::Unit::TestCase
10
- end
@@ -1,7 +0,0 @@
1
- require 'helper'
2
-
3
- class TestDmIsPersistentStateMachine < Test::Unit::TestCase
4
- should "probably rename this file and start testing for real" do
5
- flunk "hey buddy, you should probably rename this file and start testing for real"
6
- end
7
- end