stator 0.5.0 → 0.9.0.beta
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 +4 -4
- data/.github/workflows/build.yml +8 -2
- data/.gitignore +1 -0
- data/Appraisals +4 -0
- data/Gemfile +1 -0
- data/gemfiles/activerecord_5.1.gemfile +1 -0
- data/gemfiles/activerecord_5.1.gemfile.lock +12 -2
- data/gemfiles/activerecord_5.2.gemfile +1 -0
- data/gemfiles/activerecord_5.2.gemfile.lock +12 -2
- data/gemfiles/activerecord_5.gemfile +12 -0
- data/gemfiles/activerecord_5.gemfile.lock +74 -0
- data/gemfiles/activerecord_6.0.gemfile +1 -0
- data/gemfiles/activerecord_6.0.gemfile.lock +12 -2
- data/gemfiles/activerecord_6.1.gemfile +1 -0
- data/gemfiles/activerecord_6.1.gemfile.lock +12 -2
- data/gemfiles/activerecord_7.0.gemfile +1 -0
- data/gemfiles/activerecord_7.0.gemfile.lock +12 -2
- data/lib/stator/alias.rb +51 -30
- data/lib/stator/integration.rb +42 -49
- data/lib/stator/machine.rb +59 -58
- data/lib/stator/model.rb +78 -73
- data/lib/stator/transition.rb +61 -60
- data/lib/stator/version.rb +3 -5
- data/lib/stator.rb +13 -0
- data/spec/model_spec.rb +203 -239
- data/spec/spec_helper.rb +6 -3
- data/spec/support/models.rb +26 -45
- data/spec/support/schema.rb +42 -42
- data/stator.gemspec +1 -1
- metadata +21 -5
data/lib/stator/transition.rb
CHANGED
@@ -1,44 +1,39 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module Stator
|
2
4
|
class Transition
|
3
|
-
|
4
|
-
ANY = '__any__'
|
5
|
-
|
6
|
-
attr_reader :name
|
7
|
-
attr_reader :full_name
|
5
|
+
attr_reader :namespace, :name, :attr_name, :from_states, :to_state, :class_name, :callbacks
|
8
6
|
|
9
7
|
def initialize(class_name, name, namespace = nil)
|
10
|
-
@class_name
|
11
|
-
@name
|
12
|
-
@namespace
|
13
|
-
@
|
14
|
-
@
|
15
|
-
@
|
16
|
-
@callbacks = {}
|
8
|
+
@class_name = class_name
|
9
|
+
@name = name&.to_sym
|
10
|
+
@namespace = namespace&.to_sym
|
11
|
+
@from_states = []
|
12
|
+
@to_state = nil
|
13
|
+
@callbacks = {}
|
17
14
|
end
|
18
15
|
|
19
|
-
def
|
20
|
-
@
|
16
|
+
def attr_name
|
17
|
+
@attr_name ||= generate_attr_name
|
21
18
|
end
|
22
19
|
|
23
|
-
def
|
24
|
-
@
|
20
|
+
def from_states(*new_froms)
|
21
|
+
@from_states |= new_froms
|
25
22
|
end
|
23
|
+
alias from from_states
|
26
24
|
|
27
|
-
def
|
28
|
-
@
|
29
|
-
end
|
30
|
-
|
31
|
-
def from_states
|
32
|
-
@froms
|
25
|
+
def to(new_to)
|
26
|
+
@to_state = new_to
|
33
27
|
end
|
34
28
|
|
35
29
|
def can?(current_state)
|
36
|
-
|
30
|
+
from_states.include?(current_state) || from_states.include?(Stator::ANY) || current_state == Stator::ANY
|
37
31
|
end
|
38
32
|
|
39
|
-
def valid?(
|
40
|
-
|
41
|
-
|
33
|
+
def valid?(from_check, to_check)
|
34
|
+
from_check = from_check&.to_sym # coming from the database, i suspect
|
35
|
+
|
36
|
+
can?(from_check) && (to_check == to_state || to_check == ANY || to_state == ANY)
|
42
37
|
end
|
43
38
|
|
44
39
|
def conditional(options = {}, &block)
|
@@ -46,79 +41,85 @@ module Stator
|
|
46
41
|
end
|
47
42
|
|
48
43
|
def any
|
49
|
-
ANY
|
44
|
+
Stator::ANY
|
50
45
|
end
|
51
46
|
|
52
47
|
def evaluate
|
53
|
-
generate_methods
|
48
|
+
generate_methods if attr_name.present?
|
54
49
|
end
|
55
50
|
|
56
|
-
|
51
|
+
private
|
57
52
|
|
58
53
|
def klass
|
59
|
-
|
54
|
+
class_name.constantize
|
55
|
+
end
|
56
|
+
|
57
|
+
def generate_attr_name
|
58
|
+
if namespace == Stator.default_namespace
|
59
|
+
name
|
60
|
+
else
|
61
|
+
[namespace, name].compact.join('_').to_sym
|
62
|
+
end
|
60
63
|
end
|
61
64
|
|
62
65
|
def callbacks(kind)
|
63
|
-
|
66
|
+
callbacks[kind] || []
|
64
67
|
end
|
65
68
|
|
66
69
|
def conditional_block(options = {})
|
67
70
|
options[:use_previous] ||= false
|
68
71
|
|
69
|
-
_namespace =
|
70
|
-
_froms =
|
71
|
-
_to =
|
72
|
-
|
73
|
-
|
74
|
-
(
|
75
|
-
|
76
|
-
) &&
|
77
|
-
_froms.include?(
|
78
|
-
_froms.include?(
|
79
|
-
|
80
|
-
self._stator(_namespace).integration(self).state == _to ||
|
81
|
-
_to == ::Stator::Transition::ANY
|
82
|
-
)
|
72
|
+
_namespace = namespace
|
73
|
+
_froms = from_states
|
74
|
+
_to = to_state
|
75
|
+
|
76
|
+
proc do
|
77
|
+
integration = self.class._stator(_namespace).integration(self)
|
78
|
+
|
79
|
+
integration.state_changed?(options[:use_previous]) &&
|
80
|
+
_froms.include?(integration.state_was(options[:use_previous])) ||
|
81
|
+
_froms.include?(Stator::ANY) &&
|
82
|
+
integration.state == _to || _to == Stator::ANY
|
83
83
|
end
|
84
84
|
end
|
85
85
|
|
86
86
|
def generate_methods
|
87
87
|
klass.class_eval <<-EV, __FILE__, __LINE__ + 1
|
88
|
-
def #{
|
89
|
-
integration =
|
88
|
+
def #{attr_name}(should_save = true)
|
89
|
+
integration = _stator_integration(:#{namespace})
|
90
90
|
|
91
|
-
unless can_#{
|
92
|
-
integration.invalid_transition!(integration.state,
|
91
|
+
unless can_#{attr_name}?
|
92
|
+
integration.invalid_transition!(integration.state, :#{to_state}) if should_save
|
93
93
|
return false
|
94
94
|
end
|
95
95
|
|
96
|
-
integration.state =
|
96
|
+
integration.state = :#{to_state}
|
97
|
+
|
97
98
|
self.save if should_save
|
98
99
|
end
|
99
100
|
|
100
|
-
def #{
|
101
|
-
integration =
|
101
|
+
def #{attr_name}!
|
102
|
+
integration = _stator_integration(:#{namespace})
|
102
103
|
|
103
|
-
unless can_#{
|
104
|
-
integration.invalid_transition!(integration.state,
|
104
|
+
unless can_#{attr_name}?
|
105
|
+
integration.invalid_transition!(integration.state, :#{to_state})
|
105
106
|
raise ActiveRecord::RecordInvalid.new(self)
|
106
107
|
end
|
107
108
|
|
108
|
-
integration.state =
|
109
|
+
integration.state = :#{to_state}
|
109
110
|
self.save!
|
110
111
|
end
|
111
112
|
|
112
|
-
def can_#{
|
113
|
-
integration =
|
113
|
+
def can_#{attr_name}?
|
114
|
+
integration = _stator_integration(:#{namespace})
|
114
115
|
return true if integration.skip_validations
|
115
116
|
|
116
|
-
machine = self._stator(
|
117
|
-
transition = machine.transitions.detect{|t| t.
|
117
|
+
machine = self._stator(:#{namespace})
|
118
|
+
transition = machine.transitions.detect { |t| t.attr_name == :#{attr_name} }
|
119
|
+
|
118
120
|
transition.can?(integration.state)
|
119
121
|
end
|
120
122
|
EV
|
121
123
|
end
|
122
|
-
|
123
124
|
end
|
124
125
|
end
|
data/lib/stator/version.rb
CHANGED
@@ -1,12 +1,10 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
module Stator
|
4
|
-
|
5
4
|
MAJOR = 0
|
6
|
-
MINOR =
|
5
|
+
MINOR = 9
|
7
6
|
PATCH = 0
|
8
|
-
PRERELEASE =
|
9
|
-
|
10
|
-
VERSION = [MAJOR, MINOR, PATCH, PRERELEASE].compact.join(".")
|
7
|
+
PRERELEASE = "beta"
|
11
8
|
|
9
|
+
VERSION = [MAJOR, MINOR, PATCH, PRERELEASE].compact.join('.')
|
12
10
|
end
|
data/lib/stator.rb
CHANGED
@@ -1,6 +1,19 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require 'stator/version'
|
2
4
|
require 'stator/alias'
|
3
5
|
require 'stator/integration'
|
4
6
|
require 'stator/machine'
|
5
7
|
require 'stator/model'
|
6
8
|
require 'stator/transition'
|
9
|
+
|
10
|
+
require 'active_support/concern'
|
11
|
+
require 'debug'
|
12
|
+
|
13
|
+
module Stator
|
14
|
+
ANY = :__ANY__
|
15
|
+
|
16
|
+
def self.default_namespace
|
17
|
+
ENV.fetch('STATOR_NAMESPACE', :default).to_sym
|
18
|
+
end
|
19
|
+
end
|