can_has_state 0.2.2 → 0.3.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/README.md +19 -4
- data/Rakefile +1 -28
- data/lib/can_has_state/definition.rb +15 -3
- data/lib/can_has_state/dirty_helper.rb +28 -0
- data/lib/can_has_state/machine.rb +3 -3
- data/lib/can_has_state/version.rb +1 -1
- data/lib/can_has_state.rb +3 -2
- data/test/can_has_state_test.rb +208 -3
- data/test/test_helper.rb +3 -14
- metadata +21 -66
- data/test/dummy/README.rdoc +0 -261
- data/test/dummy/Rakefile +0 -7
- data/test/dummy/app/assets/javascripts/application.js +0 -15
- data/test/dummy/app/assets/stylesheets/application.css +0 -13
- data/test/dummy/app/controllers/application_controller.rb +0 -3
- data/test/dummy/app/helpers/application_helper.rb +0 -2
- data/test/dummy/app/views/layouts/application.html.erb +0 -14
- data/test/dummy/config/application.rb +0 -59
- data/test/dummy/config/boot.rb +0 -10
- data/test/dummy/config/database.yml +0 -25
- data/test/dummy/config/environment.rb +0 -5
- data/test/dummy/config/environments/development.rb +0 -37
- data/test/dummy/config/environments/production.rb +0 -67
- data/test/dummy/config/environments/test.rb +0 -37
- data/test/dummy/config/initializers/backtrace_silencers.rb +0 -7
- data/test/dummy/config/initializers/inflections.rb +0 -15
- data/test/dummy/config/initializers/mime_types.rb +0 -5
- data/test/dummy/config/initializers/secret_token.rb +0 -7
- data/test/dummy/config/initializers/session_store.rb +0 -8
- data/test/dummy/config/initializers/wrap_parameters.rb +0 -14
- data/test/dummy/config/locales/en.yml +0 -5
- data/test/dummy/config/routes.rb +0 -58
- data/test/dummy/config.ru +0 -4
- data/test/dummy/public/404.html +0 -26
- data/test/dummy/public/422.html +0 -26
- data/test/dummy/public/500.html +0 -25
- data/test/dummy/public/favicon.ico +0 -0
- data/test/dummy/script/rails +0 -6
data/README.md
CHANGED
@@ -104,7 +104,8 @@ Add it to your `Gemfile`:
|
|
104
104
|
# triggers are useful for logging or cascading changes to association
|
105
105
|
# models. Deferred trigger actions are run within the same database
|
106
106
|
# transaction (for ActiveRecord and other ActiveModel children that
|
107
|
-
# implement this).
|
107
|
+
# implement this). Deferred triggers require support for after_save
|
108
|
+
# callbacks, compatible with that supported by ActiveRecord.
|
108
109
|
#
|
109
110
|
# Last, wildcards are supported. Note that the ruby parser requires a
|
110
111
|
# space after the asterisk for wildcards on the left side:
|
@@ -131,11 +132,13 @@ Add it to your `Gemfile`:
|
|
131
132
|
### Just ActiveModel ###
|
132
133
|
|
133
134
|
class Account
|
134
|
-
include
|
135
|
+
include CanHasState::DirtyHelper
|
135
136
|
include ActiveModel::Validations
|
136
137
|
include ActiveModel::Validations::Callbacks
|
137
138
|
include CanHasState::Machine
|
138
139
|
|
140
|
+
track_dirty :account_state
|
141
|
+
|
139
142
|
state_machine :account_state do
|
140
143
|
state :active, :initial,
|
141
144
|
:from => :inactive
|
@@ -148,6 +151,16 @@ Add it to your `Gemfile`:
|
|
148
151
|
|
149
152
|
end
|
150
153
|
|
154
|
+
ActiveModel::Dirty tracking must be enabled for the attribute(s) that hold the
|
155
|
+
state(s) in your model (see docs for ActiveModel::Dirty). If you're building on
|
156
|
+
top of a library that supports this (ActiveRecord, Mongoid, etc.), you're fine.
|
157
|
+
If not, CanHasState provides a helper module, `CanHasState::DirtyHelper`, that
|
158
|
+
provides the supporting implementation required by ActiveModel::Dirty. Just call
|
159
|
+
`track_dirty :attr_one, :attr_two` as shown above.
|
160
|
+
|
161
|
+
Hint: deferred triggers aren't supported with bare ActiveModel. However, if a
|
162
|
+
non-ActiveRecord persistence engine provides #after_save, then deferred triggers
|
163
|
+
will be enabled.
|
151
164
|
|
152
165
|
|
153
166
|
## Managing states ##
|
@@ -230,7 +243,9 @@ will be called.
|
|
230
243
|
## Notes on triggers and initial state ##
|
231
244
|
|
232
245
|
`can_has_state` relies on the `ActiveModel::Dirty` module to detect when a state
|
233
|
-
attribute has changed. In general, this shouldn't matter much to you
|
246
|
+
attribute has changed. In general, this shouldn't matter much to you as long as
|
247
|
+
you're using ActiveRecord, Mongoid, or something that implements full Dirty
|
248
|
+
support.
|
234
249
|
|
235
250
|
However, triggers involving initial values can be tricky. If your database
|
236
251
|
schema sets the default value to the initial value, `:on_enter` and custom
|
@@ -242,4 +257,4 @@ because the initial state value changed from nil to the initial state.
|
|
242
257
|
|
243
258
|
## Compatibility ##
|
244
259
|
|
245
|
-
Tested with Ruby 1.9 and ActiveSupport and ActiveModel
|
260
|
+
Tested with Ruby 1.9 and ActiveSupport and ActiveModel 4.0.
|
data/Rakefile
CHANGED
@@ -1,30 +1,4 @@
|
|
1
|
-
|
2
|
-
begin
|
3
|
-
require 'bundler/setup'
|
4
|
-
rescue LoadError
|
5
|
-
puts 'You must `gem install bundler` and `bundle install` to run rake tasks'
|
6
|
-
end
|
7
|
-
begin
|
8
|
-
require 'rdoc/task'
|
9
|
-
rescue LoadError
|
10
|
-
require 'rdoc/rdoc'
|
11
|
-
require 'rake/rdoctask'
|
12
|
-
RDoc::Task = Rake::RDocTask
|
13
|
-
end
|
14
|
-
|
15
|
-
RDoc::Task.new(:rdoc) do |rdoc|
|
16
|
-
rdoc.rdoc_dir = 'rdoc'
|
17
|
-
rdoc.title = 'CanHasState'
|
18
|
-
rdoc.options << '--line-numbers'
|
19
|
-
rdoc.rdoc_files.include('README.rdoc')
|
20
|
-
rdoc.rdoc_files.include('lib/**/*.rb')
|
21
|
-
end
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
Bundler::GemHelper.install_tasks
|
27
|
-
|
1
|
+
require 'bundler/gem_tasks'
|
28
2
|
require 'rake/testtask'
|
29
3
|
|
30
4
|
Rake::TestTask.new(:test) do |t|
|
@@ -34,5 +8,4 @@ Rake::TestTask.new(:test) do |t|
|
|
34
8
|
t.verbose = false
|
35
9
|
end
|
36
10
|
|
37
|
-
|
38
11
|
task :default => :test
|
@@ -35,20 +35,26 @@ module CanHasState
|
|
35
35
|
when :from
|
36
36
|
from_vals = Array(val).map(&:to_s)
|
37
37
|
from_vals << nil # for new records
|
38
|
-
guards << Proc.new
|
38
|
+
guards << Proc.new do |r|
|
39
|
+
val_was = r.send("#{column}_was")
|
40
|
+
val_was &&= val_was.to_s
|
41
|
+
from_vals.include? val_was
|
42
|
+
end
|
39
43
|
when :guard, :require
|
40
44
|
guards += Array(val)
|
41
45
|
when :message
|
42
46
|
message = val
|
43
47
|
when :timestamp
|
44
|
-
@triggers << {:from=>["*"], :to=>[state_name], :trigger=>[Proc.new{|r| r.send("#{val}=", Time.
|
48
|
+
@triggers << {:from=>["*"], :to=>[state_name], :trigger=>[Proc.new{|r| r.send("#{val}=", Time.now.utc)}]}
|
45
49
|
when :on_enter
|
46
50
|
@triggers << {:from=>["*"], :to=>[state_name], :trigger=>Array(val), :type=>:on_enter}
|
47
51
|
when :on_enter_deferred
|
52
|
+
raise(ArgumentError, "use of deferred triggers requires support for #after_save callbacks") unless respond_to?(:after_save)
|
48
53
|
@triggers << {:from=>["*"], :to=>[state_name], :trigger=>Array(val), :type=>:on_enter, :deferred=>true}
|
49
54
|
when :on_exit
|
50
55
|
@triggers << {:from=>[state_name], :to=>["*"], :trigger=>Array(val), :type=>:on_exit}
|
51
56
|
when :on_exit_deferred
|
57
|
+
raise(ArgumentError, "use of deferred triggers requires support for #after_save callbacks") unless respond_to?(:after_save)
|
52
58
|
@triggers << {:from=>[state_name], :to=>["*"], :trigger=>Array(val), :type=>:on_exit, :deferred=>true}
|
53
59
|
end
|
54
60
|
end
|
@@ -60,6 +66,7 @@ module CanHasState
|
|
60
66
|
def on(pairs)
|
61
67
|
trigger = pairs.delete :trigger
|
62
68
|
deferred = pairs.delete :deferred
|
69
|
+
raise(ArgumentError, "use of deferred triggers requires support for #after_save callbacks") if deferred && !respond_to?(:after_save)
|
63
70
|
pairs.each do |from, to|
|
64
71
|
@triggers << {:from=>Array(from).map(&:to_s), :to=>Array(to).map(&:to_s),
|
65
72
|
:trigger=>Array(trigger), :type=>:trigger, :deferred=>!!deferred}
|
@@ -69,10 +76,12 @@ module CanHasState
|
|
69
76
|
|
70
77
|
|
71
78
|
def known?(to)
|
72
|
-
|
79
|
+
to &&= to.to_s
|
80
|
+
@states.keys.include? to
|
73
81
|
end
|
74
82
|
|
75
83
|
def allow?(record, to)
|
84
|
+
to &&= to.to_s
|
76
85
|
return false unless known?(to)
|
77
86
|
states[to][:guards].all? do |g|
|
78
87
|
case g
|
@@ -87,11 +96,14 @@ module CanHasState
|
|
87
96
|
end
|
88
97
|
|
89
98
|
def message(to)
|
99
|
+
to &&= to.to_s
|
90
100
|
states[to][:message]
|
91
101
|
end
|
92
102
|
|
93
103
|
|
94
104
|
def trigger(record, from, to, deferred=false)
|
105
|
+
from &&= from.to_s
|
106
|
+
to &&= to.to_s
|
95
107
|
# Rails.logger.debug "Checking triggers for transition #{from} to #{to} (deferred:#{deferred.inspect})"
|
96
108
|
@triggers.select do |trigger|
|
97
109
|
deferred ? trigger[:deferred] : !trigger[:deferred]
|
@@ -0,0 +1,28 @@
|
|
1
|
+
module CanHasState
|
2
|
+
module DirtyHelper
|
3
|
+
extend ActiveSupport::Concern
|
4
|
+
|
5
|
+
included do
|
6
|
+
include ActiveModel::Dirty
|
7
|
+
end
|
8
|
+
|
9
|
+
module ClassMethods
|
10
|
+
|
11
|
+
def track_dirty(*attrs)
|
12
|
+
define_attribute_methods attrs
|
13
|
+
attrs.each do |attr|
|
14
|
+
attr = attr.to_s
|
15
|
+
attr_reader(attr) unless respond_to?(attr)
|
16
|
+
has_writer = respond_to?("#{attr}=")
|
17
|
+
define_method "#{attr}=" do |val|
|
18
|
+
send("#{attr}_will_change!") unless val == instance_variable_get("@#{attr}")
|
19
|
+
has_writer ? super(val) : instance_variable_set("@#{attr}", val)
|
20
|
+
changed_attributes.delete(attr) if attribute_was(attr) == send(attr)
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
end
|
26
|
+
|
27
|
+
end
|
28
|
+
end
|
@@ -16,7 +16,7 @@ module CanHasState
|
|
16
16
|
|
17
17
|
def extend_state_machine(column, &block)
|
18
18
|
sm = state_machines.detect{|(col, stm)| col == column}
|
19
|
-
raise("Unknown state machine #{column}") unless sm
|
19
|
+
raise(ArgumentError, "Unknown state machine #{column}") unless sm
|
20
20
|
sm[1].extend_machine &block
|
21
21
|
end
|
22
22
|
|
@@ -30,7 +30,7 @@ module CanHasState
|
|
30
30
|
before_validation :can_has_initial_states
|
31
31
|
before_validation :can_has_state_triggers
|
32
32
|
validate :can_has_valid_state_machines
|
33
|
-
after_save :can_has_deferred_state_triggers
|
33
|
+
after_save :can_has_deferred_state_triggers if respond_to?(:after_save)
|
34
34
|
end
|
35
35
|
|
36
36
|
|
@@ -81,7 +81,7 @@ module CanHasState
|
|
81
81
|
from, to = send("#{column}_was"), send(column)
|
82
82
|
next if from == to
|
83
83
|
if !sm.known?(to)
|
84
|
-
err << [column, "is not a known state"]
|
84
|
+
err << [column, "is not in a known state"]
|
85
85
|
elsif !sm.allow?(self, to) #state_machine_allow?(column, to)
|
86
86
|
err << [column, sm.message(to) % {:from=>from, :to=>to}]
|
87
87
|
end
|
data/lib/can_has_state.rb
CHANGED
@@ -1,7 +1,8 @@
|
|
1
1
|
require 'active_support'
|
2
2
|
require 'active_model'
|
3
3
|
|
4
|
-
|
5
|
-
require
|
4
|
+
%w(definition dirty_helper machine).each do |f|
|
5
|
+
require "can_has_state/#{f}"
|
6
|
+
end
|
6
7
|
|
7
8
|
require 'can_has_state/railtie' if defined?(Rails)
|
data/test/can_has_state_test.rb
CHANGED
@@ -1,7 +1,212 @@
|
|
1
1
|
require 'test_helper'
|
2
2
|
|
3
|
-
class
|
4
|
-
|
5
|
-
|
3
|
+
class Account
|
4
|
+
include ActiveModel::Validations
|
5
|
+
include ActiveModel::Validations::Callbacks
|
6
|
+
include CanHasState::DirtyHelper
|
7
|
+
include CanHasState::Machine
|
8
|
+
|
9
|
+
attr_accessor :deleted_at, :undeleted, :allow_special
|
10
|
+
track_dirty :account_state
|
11
|
+
|
12
|
+
state_machine :account_state do
|
13
|
+
state :active,
|
14
|
+
from: [:inactive, :special]
|
15
|
+
state :special,
|
16
|
+
require: :allow_special
|
17
|
+
state :inactive,
|
18
|
+
from: [:active, :deleted, :special]
|
19
|
+
state :deleted,
|
20
|
+
from: [:active, :inactive],
|
21
|
+
timestamp: :deleted_at
|
22
|
+
on :deleted => :*, trigger: ->(acct){ acct.undeleted = true }
|
23
|
+
end
|
24
|
+
|
25
|
+
def fake_persist
|
26
|
+
if valid?
|
27
|
+
# just reset dirty tracking and pretend all is good
|
28
|
+
changed_attributes.clear
|
29
|
+
true
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
class UserBare ; end
|
35
|
+
class UserState
|
36
|
+
include ActiveModel::Validations
|
37
|
+
include ActiveModel::Validations::Callbacks
|
38
|
+
include CanHasState::Machine
|
39
|
+
state_machine :state do
|
40
|
+
state :awesome
|
41
|
+
state :fabulous, :initial
|
42
|
+
end
|
43
|
+
end
|
44
|
+
class UserExtended
|
45
|
+
include ActiveModel::Validations
|
46
|
+
include ActiveModel::Validations::Callbacks
|
47
|
+
include CanHasState::Machine
|
48
|
+
state_machine :state do
|
49
|
+
state :awesome
|
50
|
+
state :fabulous, :initial
|
51
|
+
end
|
52
|
+
extend_state_machine :state do
|
53
|
+
state :incredible, :initial
|
54
|
+
end
|
55
|
+
extend_state_machine :state do
|
56
|
+
state :fantastic
|
57
|
+
end
|
58
|
+
end
|
59
|
+
class UserPreState
|
60
|
+
include ActiveModel::Validations
|
61
|
+
include ActiveModel::Validations::Callbacks
|
62
|
+
include CanHasState::Machine
|
63
|
+
end
|
64
|
+
|
65
|
+
class CanHasStateTest < MiniTest::Unit::TestCase #Minitest::Test
|
66
|
+
|
67
|
+
def test_builder_simple
|
68
|
+
refute UserBare.respond_to?(:state_machine)
|
69
|
+
assert UserState.respond_to?(:state_machine)
|
70
|
+
assert UserState.respond_to?(:state_machines)
|
71
|
+
assert UserState.new.respond_to?(:allow_state?)
|
72
|
+
assert_equal 1, UserState.state_machines.size
|
73
|
+
sm = UserState.state_machines[0][1]
|
74
|
+
assert_equal :state, sm.column
|
75
|
+
assert_equal 2, sm.states.size
|
76
|
+
assert_equal 0, sm.triggers.size
|
77
|
+
assert_equal 'fabulous', sm.initial_state
|
78
|
+
end
|
79
|
+
|
80
|
+
def test_builder_extended
|
81
|
+
assert_equal 1, UserExtended.state_machines.size
|
82
|
+
sm = UserExtended.state_machines[0][1]
|
83
|
+
assert_equal :state, sm.column
|
84
|
+
assert_equal 4, sm.states.size
|
85
|
+
assert_equal 0, sm.triggers.size
|
86
|
+
assert_equal 'incredible', sm.initial_state
|
87
|
+
end
|
88
|
+
|
89
|
+
def test_extending
|
90
|
+
assert_raises(ArgumentError) do
|
91
|
+
UserState.class_eval do
|
92
|
+
extend_state_machine :doesnt_exist do
|
93
|
+
state :phantom
|
94
|
+
end
|
95
|
+
end
|
96
|
+
end
|
97
|
+
end
|
98
|
+
|
99
|
+
def test_deferred_unavailable
|
100
|
+
assert_raises(ArgumentError) do
|
101
|
+
UserPreState.class_eval do
|
102
|
+
state_machine :state_one do
|
103
|
+
state :one, on_enter_deferred: ->{ raise "Shouldn't get here" }
|
104
|
+
end
|
105
|
+
end
|
106
|
+
end
|
107
|
+
|
108
|
+
assert_raises(ArgumentError) do
|
109
|
+
UserPreState.class_eval do
|
110
|
+
state_machine :state_two do
|
111
|
+
state :two, on_exit_deferred: ->{ raise "Shouldn't get here" }
|
112
|
+
end
|
113
|
+
end
|
114
|
+
end
|
115
|
+
|
116
|
+
assert_raises(ArgumentError) do
|
117
|
+
UserPreState.class_eval do
|
118
|
+
state_machine :state_three do
|
119
|
+
state :three
|
120
|
+
on :* => :*, trigger: ->{ raise "Shouldn't get here" }, deferred: true
|
121
|
+
end
|
122
|
+
end
|
123
|
+
end
|
6
124
|
end
|
125
|
+
|
126
|
+
def test_builder_complex
|
127
|
+
assert_equal 1, Account.state_machines.size
|
128
|
+
sm = Account.state_machines[0][1]
|
129
|
+
assert_equal :account_state, sm.column
|
130
|
+
assert_equal 4, sm.states.size
|
131
|
+
assert_equal 2, sm.triggers.size
|
132
|
+
assert_equal 'active', sm.initial_state
|
133
|
+
end
|
134
|
+
|
135
|
+
def test_state_builder
|
136
|
+
sm_acct = Account.state_machines[0][1]
|
137
|
+
sm_user = UserState.state_machines[0][1]
|
138
|
+
assert_equal 0, sm_user.states['awesome'][:guards].size
|
139
|
+
assert_equal 1, sm_acct.states['active'][:guards].size
|
140
|
+
end
|
141
|
+
|
142
|
+
|
143
|
+
def test_dirty_helper
|
144
|
+
assert Account.new.respond_to?(:account_state)
|
145
|
+
assert Account.new.respond_to?(:account_state_was)
|
146
|
+
|
147
|
+
a = Account.new
|
148
|
+
a.fake_persist
|
149
|
+
assert_equal 'active', a.account_state
|
150
|
+
assert_equal 'active', a.account_state_was
|
151
|
+
a.account_state = 'inactive'
|
152
|
+
assert_equal 'inactive', a.account_state
|
153
|
+
assert_equal 'active', a.account_state_was
|
154
|
+
a.fake_persist
|
155
|
+
assert_equal 'inactive', a.account_state
|
156
|
+
assert_equal 'inactive', a.account_state_was
|
157
|
+
end
|
158
|
+
|
159
|
+
def test_state_vals
|
160
|
+
a = Account.new
|
161
|
+
a.account_state = :inactive
|
162
|
+
assert a.valid?, "Should be valid; got errors: #{a.errors.to_a}"
|
163
|
+
|
164
|
+
a = Account.new
|
165
|
+
a.account_state = 'inactive'
|
166
|
+
assert a.valid?, "Should be valid; got errors: #{a.errors.to_a}"
|
167
|
+
|
168
|
+
a = Account.new
|
169
|
+
a.account_state = 'madeup'
|
170
|
+
refute a.valid?
|
171
|
+
assert_equal ['Account state is not in a known state'], a.errors.to_a
|
172
|
+
end
|
173
|
+
|
174
|
+
def test_triggers
|
175
|
+
a = Account.new
|
176
|
+
a.fake_persist
|
177
|
+
assert_equal 'active', a.account_state
|
178
|
+
refute a.deleted_at
|
179
|
+
refute a.undeleted
|
180
|
+
|
181
|
+
a.account_state = 'deleted'
|
182
|
+
assert a.fake_persist
|
183
|
+
assert_kind_of Time, a.deleted_at
|
184
|
+
refute a.undeleted
|
185
|
+
|
186
|
+
a.account_state = 'inactive'
|
187
|
+
assert a.fake_persist, "Unexpected error: #{a.errors.to_a}"
|
188
|
+
assert a.undeleted, 'Expecting undeleted to be set'
|
189
|
+
end
|
190
|
+
|
191
|
+
def test_guards
|
192
|
+
a = Account.new
|
193
|
+
a.account_state = 'deleted'
|
194
|
+
assert a.fake_persist
|
195
|
+
|
196
|
+
a.account_state = 'active'
|
197
|
+
a.valid?
|
198
|
+
assert_match /invalid transition/, a.errors.to_a.first
|
199
|
+
|
200
|
+
a.account_state = 'inactive'
|
201
|
+
assert a.valid?, "Errors: #{a.errors.to_a}"
|
202
|
+
|
203
|
+
|
204
|
+
a.account_state = 'special'
|
205
|
+
a.valid?
|
206
|
+
assert_match /invalid transition/, a.errors.to_a.first
|
207
|
+
|
208
|
+
a.allow_special = true
|
209
|
+
assert a.valid?, "Errors: #{a.errors.to_a}"
|
210
|
+
end
|
211
|
+
|
7
212
|
end
|
data/test/test_helper.rb
CHANGED
@@ -1,15 +1,4 @@
|
|
1
|
-
|
2
|
-
|
1
|
+
require 'minitest/autorun'
|
2
|
+
require 'turn'
|
3
3
|
|
4
|
-
require
|
5
|
-
require "rails/test_help"
|
6
|
-
|
7
|
-
Rails.backtrace_cleaner.remove_silencers!
|
8
|
-
|
9
|
-
# Load support files
|
10
|
-
Dir["#{File.dirname(__FILE__)}/support/**/*.rb"].each { |f| require f }
|
11
|
-
|
12
|
-
# Load fixtures from the engine
|
13
|
-
if ActiveSupport::TestCase.method_defined?(:fixture_path=)
|
14
|
-
ActiveSupport::TestCase.fixture_path = File.expand_path("../fixtures", __FILE__)
|
15
|
-
end
|
4
|
+
require 'can_has_state'
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: can_has_state
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.3.0
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2013-
|
12
|
+
date: 2013-07-13 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: activemodel
|
@@ -56,7 +56,23 @@ dependencies:
|
|
56
56
|
- !ruby/object:Gem::Version
|
57
57
|
version: '5.0'
|
58
58
|
- !ruby/object:Gem::Dependency
|
59
|
-
name:
|
59
|
+
name: minitest
|
60
|
+
requirement: !ruby/object:Gem::Requirement
|
61
|
+
none: false
|
62
|
+
requirements:
|
63
|
+
- - ~>
|
64
|
+
- !ruby/object:Gem::Version
|
65
|
+
version: '4.2'
|
66
|
+
type: :development
|
67
|
+
prerelease: false
|
68
|
+
version_requirements: !ruby/object:Gem::Requirement
|
69
|
+
none: false
|
70
|
+
requirements:
|
71
|
+
- - ~>
|
72
|
+
- !ruby/object:Gem::Version
|
73
|
+
version: '4.2'
|
74
|
+
- !ruby/object:Gem::Dependency
|
75
|
+
name: turn
|
60
76
|
requirement: !ruby/object:Gem::Requirement
|
61
77
|
none: false
|
62
78
|
requirements:
|
@@ -80,6 +96,7 @@ extensions: []
|
|
80
96
|
extra_rdoc_files: []
|
81
97
|
files:
|
82
98
|
- lib/can_has_state/definition.rb
|
99
|
+
- lib/can_has_state/dirty_helper.rb
|
83
100
|
- lib/can_has_state/machine.rb
|
84
101
|
- lib/can_has_state/railtie.rb
|
85
102
|
- lib/can_has_state/version.rb
|
@@ -89,34 +106,6 @@ files:
|
|
89
106
|
- Rakefile
|
90
107
|
- README.md
|
91
108
|
- test/can_has_state_test.rb
|
92
|
-
- test/dummy/app/assets/javascripts/application.js
|
93
|
-
- test/dummy/app/assets/stylesheets/application.css
|
94
|
-
- test/dummy/app/controllers/application_controller.rb
|
95
|
-
- test/dummy/app/helpers/application_helper.rb
|
96
|
-
- test/dummy/app/views/layouts/application.html.erb
|
97
|
-
- test/dummy/config/application.rb
|
98
|
-
- test/dummy/config/boot.rb
|
99
|
-
- test/dummy/config/database.yml
|
100
|
-
- test/dummy/config/environment.rb
|
101
|
-
- test/dummy/config/environments/development.rb
|
102
|
-
- test/dummy/config/environments/production.rb
|
103
|
-
- test/dummy/config/environments/test.rb
|
104
|
-
- test/dummy/config/initializers/backtrace_silencers.rb
|
105
|
-
- test/dummy/config/initializers/inflections.rb
|
106
|
-
- test/dummy/config/initializers/mime_types.rb
|
107
|
-
- test/dummy/config/initializers/secret_token.rb
|
108
|
-
- test/dummy/config/initializers/session_store.rb
|
109
|
-
- test/dummy/config/initializers/wrap_parameters.rb
|
110
|
-
- test/dummy/config/locales/en.yml
|
111
|
-
- test/dummy/config/routes.rb
|
112
|
-
- test/dummy/config.ru
|
113
|
-
- test/dummy/public/404.html
|
114
|
-
- test/dummy/public/422.html
|
115
|
-
- test/dummy/public/500.html
|
116
|
-
- test/dummy/public/favicon.ico
|
117
|
-
- test/dummy/Rakefile
|
118
|
-
- test/dummy/README.rdoc
|
119
|
-
- test/dummy/script/rails
|
120
109
|
- test/test_helper.rb
|
121
110
|
homepage: https://github.com/zarqman/can_has_state
|
122
111
|
licenses: []
|
@@ -130,52 +119,18 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
130
119
|
- - ! '>='
|
131
120
|
- !ruby/object:Gem::Version
|
132
121
|
version: '0'
|
133
|
-
segments:
|
134
|
-
- 0
|
135
|
-
hash: 1517895089536744781
|
136
122
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
137
123
|
none: false
|
138
124
|
requirements:
|
139
125
|
- - ! '>='
|
140
126
|
- !ruby/object:Gem::Version
|
141
127
|
version: '0'
|
142
|
-
segments:
|
143
|
-
- 0
|
144
|
-
hash: 1517895089536744781
|
145
128
|
requirements: []
|
146
129
|
rubyforge_project:
|
147
|
-
rubygems_version: 1.8.
|
130
|
+
rubygems_version: 1.8.25
|
148
131
|
signing_key:
|
149
132
|
specification_version: 3
|
150
133
|
summary: Super simple state machine for ActiveModel
|
151
134
|
test_files:
|
152
135
|
- test/can_has_state_test.rb
|
153
|
-
- test/dummy/app/assets/javascripts/application.js
|
154
|
-
- test/dummy/app/assets/stylesheets/application.css
|
155
|
-
- test/dummy/app/controllers/application_controller.rb
|
156
|
-
- test/dummy/app/helpers/application_helper.rb
|
157
|
-
- test/dummy/app/views/layouts/application.html.erb
|
158
|
-
- test/dummy/config/application.rb
|
159
|
-
- test/dummy/config/boot.rb
|
160
|
-
- test/dummy/config/database.yml
|
161
|
-
- test/dummy/config/environment.rb
|
162
|
-
- test/dummy/config/environments/development.rb
|
163
|
-
- test/dummy/config/environments/production.rb
|
164
|
-
- test/dummy/config/environments/test.rb
|
165
|
-
- test/dummy/config/initializers/backtrace_silencers.rb
|
166
|
-
- test/dummy/config/initializers/inflections.rb
|
167
|
-
- test/dummy/config/initializers/mime_types.rb
|
168
|
-
- test/dummy/config/initializers/secret_token.rb
|
169
|
-
- test/dummy/config/initializers/session_store.rb
|
170
|
-
- test/dummy/config/initializers/wrap_parameters.rb
|
171
|
-
- test/dummy/config/locales/en.yml
|
172
|
-
- test/dummy/config/routes.rb
|
173
|
-
- test/dummy/config.ru
|
174
|
-
- test/dummy/public/404.html
|
175
|
-
- test/dummy/public/422.html
|
176
|
-
- test/dummy/public/500.html
|
177
|
-
- test/dummy/public/favicon.ico
|
178
|
-
- test/dummy/Rakefile
|
179
|
-
- test/dummy/README.rdoc
|
180
|
-
- test/dummy/script/rails
|
181
136
|
- test/test_helper.rb
|