stateful 0.0.4 → 0.0.5

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 43a52ed260948a8b25ab8e179b6cc1a4279243b8
4
- data.tar.gz: 0099bcace08e9525183ff80bb81b4f8b3b32d6ee
3
+ metadata.gz: d44fb4b6fd8eb3e91311d9bd585755672d044a25
4
+ data.tar.gz: 3a06ef8db37c2e377d6e965114da621fb11436fd
5
5
  SHA512:
6
- metadata.gz: 01255d072732c11031920c57d6fbadc3c9242329ae4cb7ab4d07239e0a7cb2cebefa34cb7eedd7d4c73ed109764a14f64eb98300acbc34447a818383dce33009
7
- data.tar.gz: ac27cc34184bbc0cd40676fd2cf1c198b61630080f2d6bd472bd2b30cdf7cdbee4dfe651df688e033d96cbf1085c3dd8326ef85107ab154bcc1ac936d3fea273
6
+ metadata.gz: f9a1883570f2801945dad7004658acf175e098014226306d961a003a729f6ee8f0e8c78715bcf460377439b9b8947e05aeb06fe6793a834d879aecee021a4a28
7
+ data.tar.gz: cd0d56bff87db358ec8d8ebf866d840d88a7ed47188773e1bddad22f97b14308307df9f2cba316c49281cd8e2aa891520cece2e1a10be0203acfbf9c2968e4b4
@@ -65,34 +65,81 @@ module Stateful
65
65
  # options[:event] = calling_method if state_events.include? calling_method
66
66
  #end
67
67
 
68
- callbacks = ["#{name}_change".to_sym]
69
- callbacks << options[:event] if options[:event]
70
- run_callbacks *callbacks do
71
- __send__("#{name}=", new_state)
72
- block.call if block
73
-
74
- ## if a specific persist method value was provided
75
- if options.has_key?(:persist_method)
76
- # call the method if one was provided
77
- __send__(options[:persist_method]) if options[:persist_method]
78
- # if no persist method option was provided than use the defaults
79
- else
80
- method = persist_methods.find {|m| respond_to?(m)}
81
- __send__(method) if method
68
+ run_callbacks "#{name}_change".to_sym, new_state do
69
+
70
+ run_callbacks (options[:event] || "#{name}_non_event_change") do
71
+ __send__("#{name}=", new_state)
72
+ block.call if block
73
+
74
+ ## if a specific persist method value was provided
75
+ if options.has_key?(:persist_method)
76
+ # call the method if one was provided
77
+ __send__(options[:persist_method]) if options[:persist_method]
78
+ # if no persist method option was provided than use the defaults
79
+ else
80
+ method = persist_methods.find {|m| respond_to?(m)}
81
+ if method
82
+ __send__(method)
83
+ else
84
+ true
85
+ end
86
+ end
82
87
  end
83
88
  end
84
- true
85
89
  end
86
90
 
87
91
  protected "change_#{name}"
88
92
  protected "change_#{name}!"
89
93
  private :_change_state
90
94
 
95
+ ## state events support:
96
+
97
+ # provide a reader so that the current event being fired can be accessed
98
+ attr_reader "#{name}_event".to_sym
99
+
100
+ define_singleton_method "#{name}_event" do |event, &block|
101
+ define_method(event) do
102
+ instance_variable_set("@#{name}_change_method", "change_#{name}")
103
+ instance_variable_set("@#{name}_event", event)
104
+ begin
105
+ result = instance_eval &block
106
+ ensure
107
+ instance_variable_set("@#{name}_change_method", nil)
108
+ instance_variable_set("@#{name}_event", nil)
109
+ end
110
+ result
111
+ end
112
+
113
+ define_method("#{event}!") do
114
+ instance_variable_set("@#{name}_change_method", "change_#{name}!")
115
+ instance_variable_set("@#{name}_event", event)
116
+ begin
117
+ result = instance_eval &block
118
+ ensure
119
+ instance_variable_set("@#{name}_change_method", nil)
120
+ instance_variable_set("@#{name}_event", nil)
121
+ end
122
+ result
123
+ end
124
+ end
125
+
126
+ # define the transition_to_state method that works in conjunction with the state_event
127
+ define_method "transition_to_#{name}" do |new_state, &block|
128
+ event = __send__("#{name}_event")
129
+ raise "transition_to_#{name} can only be called while a #{name} event is being called" unless event
130
+
131
+ method = instance_variable_get("@#{name}_change_method")
132
+ __send__(method, new_state, event, &block)
133
+ end
134
+
135
+ protected "transition_to_#{name}"
136
+
91
137
  define_method "can_transition_to_#{name}?" do |new_state|
92
138
  __send__("#{name}_info").can_transition_to?(new_state)
93
139
  end
94
140
 
95
- # init and configure state info
141
+ ## init and configure state info:
142
+
96
143
  init_state_info(name, options[:states])
97
144
  __send__("#{name}_infos").values.each do |info|
98
145
  info.expand_to_transitions
@@ -106,7 +153,7 @@ module Stateful
106
153
  define_state_attribute(options)
107
154
 
108
155
  # define the event callbacks
109
- events = (["#{name}_change".to_sym] + options[:events])
156
+ events = (["#{name}_change".to_sym, "#{name}_non_event_change".to_sym] + options[:events])
110
157
  define_callbacks *events
111
158
 
112
159
  # define callback helpers
@@ -1,3 +1,3 @@
1
1
  module Stateful
2
- VERSION = "0.0.4"
2
+ VERSION = "0.0.5"
3
3
  end
@@ -4,11 +4,13 @@ require './lib/stateful'
4
4
  class Kata
5
5
  include Stateful
6
6
 
7
- attr_accessor :approved_by, :ready_score, :published_at, :state_changes
7
+ attr_accessor :approved_by, :ready_score, :published_at, :state_changes, :times_pending, :published_by
8
8
 
9
9
  def initialize
10
10
  @ready_score = 0
11
11
  @state_changes = 0
12
+ @times_pending = 0
13
+ @published_by
12
14
  end
13
15
 
14
16
  stateful default: :draft,
@@ -36,6 +38,8 @@ class Kata
36
38
  doc.state_changes += 1
37
39
  end
38
40
 
41
+
42
+
39
43
  def vote(ready)
40
44
  @ready_score += ready ? 1 : -1
41
45
 
@@ -49,24 +53,29 @@ class Kata
49
53
  end
50
54
  end
51
55
 
52
- def publish
53
- change_state(enough_votes_for_approval? ? :needs_approval : :needs_feedback) do
56
+ state_event :publish do |published_by|
57
+ transition_to_state(enough_votes_for_approval? ? :needs_approval : :needs_feedback) do
54
58
  @published_at = Time.now
59
+ @published_by = published_by
55
60
  end
56
61
  end
57
62
 
63
+ after_publish do
64
+ @times_pending += 1
65
+ end
66
+
58
67
  def unpublish
59
- change_state(:draft)
68
+ change_state(:draft, :unpublish)
60
69
  end
61
70
 
62
71
  def approve(approved_by)
63
- change_state(:approved) do
72
+ change_state(:approved, :approve) do
64
73
  @approved_by = approved_by
65
74
  end
66
75
  end
67
76
 
68
77
  def retire
69
- change_state(:retire)
78
+ change_state(:retired, :retire)
70
79
  end
71
80
 
72
81
  def enough_votes_for_approval?
@@ -147,10 +156,17 @@ describe Kata do
147
156
 
148
157
  it 'should support calling passed blocks when state is valid' do
149
158
  kata.published_at.should be_nil
150
- kata.publish
159
+ kata.publish!
151
160
  kata.published_at.should_not be_nil
152
161
  end
153
162
 
163
+ pending 'should support passing in parameters to state_event defined methods' do
164
+ kata.published_by.should be_nil
165
+ kata.publish('test')
166
+ kata.published_by.should == 'test'
167
+ kata.published?.should be_true
168
+ end
169
+
154
170
  it 'should support ingoring passed blocked when state is not valid' do
155
171
  kata.approve('test')
156
172
  kata.approved?.should be_false
@@ -160,6 +176,7 @@ describe Kata do
160
176
  it 'should support after callbacks methods' do
161
177
  kata.publish
162
178
  kata.state_changes.should == 1
179
+ kata.times_pending.should == 1
163
180
  end
164
181
 
165
182
  it 'should support can_transition_to_state?' do
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: stateful
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.4
4
+ version: 0.0.5
5
5
  platform: ruby
6
6
  authors:
7
7
  - jake hoffner
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2013-12-20 00:00:00.000000000 Z
11
+ date: 2013-12-31 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activesupport