sequel-state-machine 1.0.1 → 1.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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 1eb11cc183e1cfcfc7917f505b02b0f801888492fcf73ac6538e5915972cc799
4
- data.tar.gz: 355f305b70481b88cd306aed45e4bd6ec8b8706ecd921f17fb18e872e85ea36c
3
+ metadata.gz: 32bf94c0e52e6d2fcaf7593f02f4834f689ee462a378dfc7d561e3e29db79258
4
+ data.tar.gz: a99a5e2ccd052cecd228ccc7c702bde70b675b86afac2fbf2b69d95432a9b8b5
5
5
  SHA512:
6
- metadata.gz: e26ed08fbc26ece33859b8b68b1ce95573060437054ed1c2e7f69e751c80c5a9d0e29c0ad81ab2c2ec1985c54bcc0fd8327d940329868e7c0937b1baa0f4f64f
7
- data.tar.gz: 32164513eb750973c18e54b73defeb9aa3e45635653725733ff4c1f0f1665693a2eecb569b2d749d04010c586c86bf44f20b8558e6c44f5df85ce9c73b47c8de
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.status,
76
- to_state: self.status,
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
- current_state = self.send(self._state_value_attr).to_sym
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
- return true if state_req[:from]&.matches?(current_state)
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[self._state_value_attr]
177
+ state = self.state_machine_status
134
178
  return if states.include?(state)
135
- self.errors.add(self._state_value_attr, "status '#{state}' must be one of (#{states.sort.join(', ')})")
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.status
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.status
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.status}"
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.status}"
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(
@@ -2,6 +2,6 @@
2
2
 
3
3
  module StateMachines
4
4
  module Sequel
5
- VERSION = "1.0.1"
5
+ VERSION = "1.1.0"
6
6
  end
7
7
  end
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.1
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-03-23 00:00:00.000000000 Z
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.