sequel-state-machine 1.0.1 → 1.1.0
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
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 32bf94c0e52e6d2fcaf7593f02f4834f689ee462a378dfc7d561e3e29db79258
|
4
|
+
data.tar.gz: a99a5e2ccd052cecd228ccc7c702bde70b675b86afac2fbf2b69d95432a9b8b5
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 10d259cf6ff25cdabe78ef6699ff6fa9be62de332cd9c45901b5295be687159cbf10e7738426ab94c0f2f4f2c0af3cccf44d3ba371c026f30e00bb6677910747
|
7
|
+
data.tar.gz: 349b9378af67e386b705d9d1d6e26ca2a48ff953b322f1a47dc40da308ab240e289d1042b53acbaaf2525df408a9c05be5fd62c33b4986b28452a4d51351ced5
|
@@ -7,7 +7,53 @@ require "state_machines/sequel"
|
|
7
7
|
module Sequel
|
8
8
|
module Plugins
|
9
9
|
module StateMachine
|
10
|
+
class InvalidConfiguration < RuntimeError; end
|
11
|
+
|
12
|
+
def self.apply(_model, _opts={})
|
13
|
+
nil
|
14
|
+
end
|
15
|
+
|
16
|
+
def self.configure(model, opts={})
|
17
|
+
col = opts.is_a?(Symbol) ? opts : nil
|
18
|
+
model.instance_eval do
|
19
|
+
# See state_machine_status_column.
|
20
|
+
# We must defer defaulting the value in case the plugin
|
21
|
+
# comes ahead of the state machine (we can see a valid state machine,
|
22
|
+
# but the attribute/name will always be :state, due to some configuration
|
23
|
+
# order of operations).
|
24
|
+
@sequel_state_machine_status_column = col if col
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
10
28
|
module InstanceMethods
|
29
|
+
private def state_machine_status_column
|
30
|
+
col = self.class.instance_variable_get(:@sequel_state_machine_status_column)
|
31
|
+
return col unless col.nil?
|
32
|
+
if self.respond_to?(:_state_value_attr)
|
33
|
+
self.class.instance_variable_set(:@sequel_state_machine_status_column, self._state_value_attr)
|
34
|
+
return self._state_value_attr
|
35
|
+
end
|
36
|
+
if !self.class.respond_to?(:state_machines) || self.class.state_machines.empty?
|
37
|
+
msg = "Model must extend StateMachines::MacroMethods and have one state_machine."
|
38
|
+
raise InvalidConfiguration, msg
|
39
|
+
end
|
40
|
+
if self.class.state_machines.length > 1
|
41
|
+
msg = "Cannot use sequel-state-machine with multiple state machines. " \
|
42
|
+
"Please file an issue at https://github.com/lithictech/sequel-state-machine/issues " \
|
43
|
+
"if you need this capability."
|
44
|
+
raise InvalidConfiguration, msg
|
45
|
+
end
|
46
|
+
self.class.instance_variable_set(:@sequel_state_machine_status_column, self.class.state_machine.attribute)
|
47
|
+
end
|
48
|
+
|
49
|
+
private def state_machine_status
|
50
|
+
return self.send(self.state_machine_status_column)
|
51
|
+
end
|
52
|
+
|
53
|
+
def sequel_state_machine_status
|
54
|
+
return state_machine_status
|
55
|
+
end
|
56
|
+
|
11
57
|
def new_audit_log
|
12
58
|
audit_log_assoc = self.class.association_reflections[:audit_logs]
|
13
59
|
model = Kernel.const_get(audit_log_assoc[:class_name])
|
@@ -72,8 +118,8 @@ module Sequel
|
|
72
118
|
audlog.set(
|
73
119
|
at: Time.now,
|
74
120
|
event: event,
|
75
|
-
from_state: self.
|
76
|
-
to_state: self.
|
121
|
+
from_state: self.state_machine_status,
|
122
|
+
to_state: self.state_machine_status,
|
77
123
|
messages: audlog.class.state_machine_messages_supports_array ? messages : messages.join("\n"),
|
78
124
|
reason: reason || "",
|
79
125
|
actor: StateMachines::Sequel.current_actor,
|
@@ -114,25 +160,24 @@ module Sequel
|
|
114
160
|
|
115
161
|
# Return true if the given event can be transitioned into by the current state.
|
116
162
|
def valid_state_path_through?(event)
|
117
|
-
|
163
|
+
current_state_str = self.state_machine_status.to_s
|
164
|
+
current_state_sym = current_state_str.to_sym
|
118
165
|
event_obj = self.class.state_machine.events[event] or raise "Invalid event #{event}"
|
119
166
|
event_obj.branches.each do |branch|
|
120
167
|
branch.state_requirements.each do |state_req|
|
121
|
-
|
168
|
+
next unless (from = state_req[:from])
|
169
|
+
return true if from.matches?(current_state_str) || from.matches?(current_state_sym)
|
122
170
|
end
|
123
171
|
end
|
124
172
|
return false
|
125
173
|
end
|
126
174
|
|
127
|
-
def _state_value_attr
|
128
|
-
return @_state_value_attr ||= self.class.state_machine.attribute
|
129
|
-
end
|
130
|
-
|
131
175
|
def validates_state_machine
|
132
176
|
states = self.class.state_machine.states.map(&:value)
|
133
|
-
state = self
|
177
|
+
state = self.state_machine_status
|
134
178
|
return if states.include?(state)
|
135
|
-
self.errors.add(self.
|
179
|
+
self.errors.add(self.state_machine_status_column,
|
180
|
+
"state '#{state}' must be one of (#{states.sort.join(', ')})",)
|
136
181
|
end
|
137
182
|
end
|
138
183
|
|
@@ -36,14 +36,14 @@ module Sequel
|
|
36
36
|
|
37
37
|
module DatasetMethods
|
38
38
|
def failed
|
39
|
-
colmap = self.state_machine_column_mappings
|
39
|
+
colmap = self.model.state_machine_column_mappings
|
40
40
|
tostate_col = colmap[:to_state]
|
41
41
|
fromstate_col = colmap[:from_state]
|
42
42
|
return self.where(tostate_col => fromstate_col)
|
43
43
|
end
|
44
44
|
|
45
45
|
def succeeded
|
46
|
-
colmap = self.state_machine_column_mappings
|
46
|
+
colmap = self.model.state_machine_column_mappings
|
47
47
|
tostate_col = colmap[:to_state]
|
48
48
|
fromstate_col = colmap[:from_state]
|
49
49
|
return self.exclude(tostate_col => fromstate_col)
|
@@ -6,7 +6,7 @@ RSpec::Matchers.define :transition_on do |event|
|
|
6
6
|
match do |receiver|
|
7
7
|
raise 'must provide a "to" state' if (@to || "").to_s.empty?
|
8
8
|
receiver.send(event, *@args)
|
9
|
-
@to == receiver.
|
9
|
+
@to == receiver.send(:state_machine_status)
|
10
10
|
end
|
11
11
|
|
12
12
|
chain :to do |to_state|
|
@@ -23,10 +23,10 @@ RSpec::Matchers.define :transition_on do |event|
|
|
23
23
|
|
24
24
|
failure_message do |receiver|
|
25
25
|
msg =
|
26
|
-
if @to == receiver.
|
26
|
+
if @to == receiver.state_machine_status
|
27
27
|
"expected that event #{event} would transition, but did not"
|
28
28
|
else
|
29
|
-
"expected that event #{event} would transition to #{@to} but is #{receiver.
|
29
|
+
"expected that event #{event} would transition to #{@to} but is #{receiver.state_machine_status}"
|
30
30
|
end
|
31
31
|
(msg += "\n#{receiver.audit_logs.map(&:inspect).join("\n")}") if @audit
|
32
32
|
msg
|
@@ -43,11 +43,12 @@ RSpec::Matchers.define :not_transition_on do |event|
|
|
43
43
|
end
|
44
44
|
|
45
45
|
failure_message do |receiver|
|
46
|
-
"expected that event #{event} would not transition, but did and is now #{receiver.
|
46
|
+
"expected that event #{event} would not transition, but did and is now #{receiver.state_machine_status}"
|
47
47
|
end
|
48
48
|
end
|
49
49
|
|
50
50
|
RSpec.shared_examples "a state machine with audit logging" do |event, to_state|
|
51
|
+
let(:machine) { raise NotImplementedError, "must override let(:machine)" }
|
51
52
|
it "logs transitions" do
|
52
53
|
expect(machine).to transition_on(event).to(to_state)
|
53
54
|
expect(machine.audit_logs).to contain_exactly(
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: sequel-state-machine
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.0
|
4
|
+
version: 1.1.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Lithic Tech
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2022-
|
11
|
+
date: 2022-04-05 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rspec
|
@@ -94,6 +94,20 @@ dependencies:
|
|
94
94
|
- - "~>"
|
95
95
|
- !ruby/object:Gem::Version
|
96
96
|
version: '5.0'
|
97
|
+
- !ruby/object:Gem::Dependency
|
98
|
+
name: simplecov
|
99
|
+
requirement: !ruby/object:Gem::Requirement
|
100
|
+
requirements:
|
101
|
+
- - "~>"
|
102
|
+
- !ruby/object:Gem::Version
|
103
|
+
version: '0'
|
104
|
+
type: :development
|
105
|
+
prerelease: false
|
106
|
+
version_requirements: !ruby/object:Gem::Requirement
|
107
|
+
requirements:
|
108
|
+
- - "~>"
|
109
|
+
- !ruby/object:Gem::Version
|
110
|
+
version: '0'
|
97
111
|
- !ruby/object:Gem::Dependency
|
98
112
|
name: sqlite3
|
99
113
|
requirement: !ruby/object:Gem::Requirement
|
@@ -122,6 +136,20 @@ dependencies:
|
|
122
136
|
- - "~>"
|
123
137
|
- !ruby/object:Gem::Version
|
124
138
|
version: '0'
|
139
|
+
- !ruby/object:Gem::Dependency
|
140
|
+
name: timecop
|
141
|
+
requirement: !ruby/object:Gem::Requirement
|
142
|
+
requirements:
|
143
|
+
- - "~>"
|
144
|
+
- !ruby/object:Gem::Version
|
145
|
+
version: '0'
|
146
|
+
type: :development
|
147
|
+
prerelease: false
|
148
|
+
version_requirements: !ruby/object:Gem::Requirement
|
149
|
+
requirements:
|
150
|
+
- - "~>"
|
151
|
+
- !ruby/object:Gem::Version
|
152
|
+
version: '0'
|
125
153
|
description: |
|
126
154
|
sequel-state-machine hooks together the excellent Ruby Sequel ORM to
|
127
155
|
the state-machines library, with auditing and other tools.
|