stator 0.8.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 +10 -5
- data/.gitignore +1 -0
- data/.ruby-version +1 -1
- data/Appraisals +12 -15
- data/Gemfile +7 -6
- data/README.md +4 -20
- data/gemfiles/{activerecord_7.2.gemfile → activerecord_5.1.gemfile} +2 -1
- data/gemfiles/activerecord_5.1.gemfile.lock +74 -0
- data/gemfiles/{activerecord_8.0.gemfile → activerecord_5.2.gemfile} +2 -1
- data/gemfiles/activerecord_5.2.gemfile.lock +74 -0
- data/gemfiles/{activerecord_7.1.gemfile → activerecord_5.gemfile} +2 -1
- data/gemfiles/activerecord_5.gemfile.lock +74 -0
- data/gemfiles/activerecord_6.0.gemfile +2 -2
- data/gemfiles/activerecord_6.0.gemfile.lock +41 -69
- data/gemfiles/activerecord_6.1.gemfile +2 -2
- data/gemfiles/activerecord_6.1.gemfile.lock +41 -68
- data/gemfiles/activerecord_7.0.gemfile +2 -2
- data/gemfiles/activerecord_7.0.gemfile.lock +40 -66
- 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 -318
- data/spec/spec_helper.rb +6 -2
- data/spec/support/models.rb +26 -45
- data/spec/support/schema.rb +42 -42
- data/stator.gemspec +3 -10
- metadata +19 -75
- data/.github/CODEOWNERS +0 -1
- data/.github/dependabot.yml +0 -24
- data/gemfiles/activerecord_7.1.gemfile.lock +0 -114
- data/gemfiles/activerecord_7.2.gemfile.lock +0 -113
- data/gemfiles/activerecord_8.0.gemfile.lock +0 -116
@@ -1,62 +1,61 @@
|
|
1
1
|
PATH
|
2
2
|
remote: ..
|
3
3
|
specs:
|
4
|
-
stator (0.
|
5
|
-
activerecord
|
6
|
-
|
7
|
-
benchmark
|
8
|
-
bigdecimal
|
9
|
-
logger
|
10
|
-
mutex_m
|
4
|
+
stator (0.9.0.beta)
|
5
|
+
activerecord
|
6
|
+
activesupport
|
11
7
|
|
12
8
|
GEM
|
13
9
|
remote: https://rubygems.org/
|
14
10
|
specs:
|
15
|
-
activemodel (6.1.
|
16
|
-
activesupport (= 6.1.
|
17
|
-
activerecord (6.1.
|
18
|
-
activemodel (= 6.1.
|
19
|
-
activesupport (= 6.1.
|
20
|
-
activerecord-nulldb-adapter (
|
21
|
-
activerecord (>=
|
22
|
-
activesupport (6.1.
|
11
|
+
activemodel (6.1.6.1)
|
12
|
+
activesupport (= 6.1.6.1)
|
13
|
+
activerecord (6.1.6.1)
|
14
|
+
activemodel (= 6.1.6.1)
|
15
|
+
activesupport (= 6.1.6.1)
|
16
|
+
activerecord-nulldb-adapter (0.8.0)
|
17
|
+
activerecord (>= 5.2.0, < 7.1)
|
18
|
+
activesupport (6.1.6.1)
|
23
19
|
concurrent-ruby (~> 1.0, >= 1.0.2)
|
24
20
|
i18n (>= 1.6, < 2)
|
25
21
|
minitest (>= 5.1)
|
26
22
|
tzinfo (~> 2.0)
|
27
23
|
zeitwerk (~> 2.3)
|
28
|
-
appraisal (2.
|
24
|
+
appraisal (2.4.1)
|
29
25
|
bundler
|
30
26
|
rake
|
31
27
|
thor (>= 0.14.0)
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
diff-lcs (1.
|
37
|
-
i18n (1.
|
28
|
+
concurrent-ruby (1.1.10)
|
29
|
+
debug (1.6.1)
|
30
|
+
irb (>= 1.3.6)
|
31
|
+
reline (>= 0.3.1)
|
32
|
+
diff-lcs (1.5.0)
|
33
|
+
i18n (1.12.0)
|
38
34
|
concurrent-ruby (~> 1.0)
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
rspec-
|
49
|
-
|
35
|
+
io-console (0.5.11)
|
36
|
+
irb (1.4.1)
|
37
|
+
reline (>= 0.3.0)
|
38
|
+
minitest (5.16.2)
|
39
|
+
rake (13.0.6)
|
40
|
+
reline (0.3.1)
|
41
|
+
io-console (~> 0.5)
|
42
|
+
rspec (3.11.0)
|
43
|
+
rspec-core (~> 3.11.0)
|
44
|
+
rspec-expectations (~> 3.11.0)
|
45
|
+
rspec-mocks (~> 3.11.0)
|
46
|
+
rspec-core (3.11.0)
|
47
|
+
rspec-support (~> 3.11.0)
|
48
|
+
rspec-expectations (3.11.0)
|
50
49
|
diff-lcs (>= 1.2.0, < 2.0)
|
51
|
-
rspec-support (~> 3.
|
52
|
-
rspec-mocks (3.
|
50
|
+
rspec-support (~> 3.11.0)
|
51
|
+
rspec-mocks (3.11.1)
|
53
52
|
diff-lcs (>= 1.2.0, < 2.0)
|
54
|
-
rspec-support (~> 3.
|
55
|
-
rspec-support (3.
|
56
|
-
thor (1.
|
57
|
-
tzinfo (2.0.
|
53
|
+
rspec-support (~> 3.11.0)
|
54
|
+
rspec-support (3.11.0)
|
55
|
+
thor (1.2.1)
|
56
|
+
tzinfo (2.0.5)
|
58
57
|
concurrent-ruby (~> 1.0)
|
59
|
-
zeitwerk (2.
|
58
|
+
zeitwerk (2.6.0)
|
60
59
|
|
61
60
|
PLATFORMS
|
62
61
|
ruby
|
@@ -65,36 +64,10 @@ DEPENDENCIES
|
|
65
64
|
activerecord (~> 6.1.0)
|
66
65
|
activerecord-nulldb-adapter
|
67
66
|
appraisal
|
68
|
-
|
67
|
+
debug
|
69
68
|
rake
|
70
69
|
rspec
|
71
70
|
stator!
|
72
71
|
|
73
|
-
CHECKSUMS
|
74
|
-
activemodel (6.1.7.10) sha256=562d9b1d0597f450437ec7cd6540b13f3e074cce5c7b237ac76e7435a15d4b8c
|
75
|
-
activerecord (6.1.7.10) sha256=db1719ef443a5437badcaa1d0fb5da7db985988fb69cc37085ca6bcc569fb31a
|
76
|
-
activerecord-nulldb-adapter (1.1.1) sha256=034c91106183b954b072fba14c2786adf1a2b9e852ce04f85f823afaf03e9820
|
77
|
-
activesupport (6.1.7.10) sha256=3f8e1f787a7bfbf765959ba509ef70af8293b35cb864078919365a12bf33d470
|
78
|
-
appraisal (2.5.0) sha256=36989221be127913b0dba8d114da2001e6b2dceea7bd4951200eaba764eed3ce
|
79
|
-
base64 (0.2.0) sha256=0f25e9b21a02a0cc0cea8ef92b2041035d39350946e8789c562b2d1a3da01507
|
80
|
-
benchmark (0.4.0) sha256=0f12f8c495545e3710c3e4f0480f63f06b4c842cc94cec7f33a956f5180e874a
|
81
|
-
bigdecimal (3.1.9) sha256=2ffc742031521ad69c2dfc815a98e426a230a3d22aeac1995826a75dabfad8cc
|
82
|
-
concurrent-ruby (1.3.4) sha256=d4aa926339b0a86b5b5054a0a8c580163e6f5dcbdfd0f4bb916b1a2570731c32
|
83
|
-
diff-lcs (1.6.1) sha256=12a5a83f3e37a8e2f4427268e305914d5f1879f22b4e73bb1a09f76a3dd86cd4
|
84
|
-
i18n (1.14.7) sha256=ceba573f8138ff2c0915427f1fc5bdf4aa3ab8ae88c8ce255eb3ecf0a11a5d0f
|
85
|
-
logger (1.7.0) sha256=196edec7cc44b66cfb40f9755ce11b392f21f7967696af15d274dde7edff0203
|
86
|
-
minitest (5.25.5) sha256=391b6c6cb43a4802bfb7c93af1ebe2ac66a210293f4a3fb7db36f2fc7dc2c756
|
87
|
-
mutex_m (0.3.0) sha256=cfcb04ac16b69c4813777022fdceda24e9f798e48092a2b817eb4c0a782b0751
|
88
|
-
rake (13.2.1) sha256=46cb38dae65d7d74b6020a4ac9d48afed8eb8149c040eccf0523bec91907059d
|
89
|
-
rspec (3.13.0) sha256=d490914ac1d5a5a64a0e1400c1d54ddd2a501324d703b8cfe83f458337bab993
|
90
|
-
rspec-core (3.13.3) sha256=25136507f4f9cf2e8977a2851e64e438b4331646054e345998714108745cdfe4
|
91
|
-
rspec-expectations (3.13.3) sha256=0e6b5af59b900147698ea0ff80456c4f2e69cac4394fbd392fbd1ca561f66c58
|
92
|
-
rspec-mocks (3.13.2) sha256=2327335def0e1665325a9b617e3af9ae20272741d80ac550336309a7c59abdef
|
93
|
-
rspec-support (3.13.2) sha256=cea3a2463fd9b84b9dcc9685efd80ea701aa8f7b3decb3b3ce795ed67737dbec
|
94
|
-
stator (0.8.0)
|
95
|
-
thor (1.3.2) sha256=eef0293b9e24158ccad7ab383ae83534b7ad4ed99c09f96f1a6b036550abbeda
|
96
|
-
tzinfo (2.0.6) sha256=8daf828cc77bcf7d63b0e3bdb6caa47e2272dcfaf4fbfe46f8c3a9df087a829b
|
97
|
-
zeitwerk (2.7.2) sha256=842e067cb11eb923d747249badfb5fcdc9652d6f20a1f06453317920fdcd4673
|
98
|
-
|
99
72
|
BUNDLED WITH
|
100
|
-
2.
|
73
|
+
2.3.16
|
@@ -2,11 +2,11 @@
|
|
2
2
|
|
3
3
|
source "https://rubygems.org"
|
4
4
|
|
5
|
+
gem "activerecord", "~> 7.0.0"
|
5
6
|
gem "appraisal"
|
7
|
+
gem "debug"
|
6
8
|
gem "activerecord-nulldb-adapter"
|
7
9
|
gem "rake"
|
8
10
|
gem "rspec"
|
9
|
-
gem "activerecord", "~> 7.0.0"
|
10
|
-
gem "concurrent-ruby", "1.3.4"
|
11
11
|
|
12
12
|
gemspec path: "../"
|
@@ -1,59 +1,58 @@
|
|
1
1
|
PATH
|
2
2
|
remote: ..
|
3
3
|
specs:
|
4
|
-
stator (0.
|
5
|
-
activerecord
|
6
|
-
|
7
|
-
benchmark
|
8
|
-
bigdecimal
|
9
|
-
logger
|
10
|
-
mutex_m
|
4
|
+
stator (0.9.0.beta)
|
5
|
+
activerecord
|
6
|
+
activesupport
|
11
7
|
|
12
8
|
GEM
|
13
9
|
remote: https://rubygems.org/
|
14
10
|
specs:
|
15
|
-
activemodel (7.0.
|
16
|
-
activesupport (= 7.0.
|
17
|
-
activerecord (7.0.
|
18
|
-
activemodel (= 7.0.
|
19
|
-
activesupport (= 7.0.
|
20
|
-
activerecord-nulldb-adapter (
|
21
|
-
activerecord (>=
|
22
|
-
activesupport (7.0.
|
11
|
+
activemodel (7.0.3.1)
|
12
|
+
activesupport (= 7.0.3.1)
|
13
|
+
activerecord (7.0.3.1)
|
14
|
+
activemodel (= 7.0.3.1)
|
15
|
+
activesupport (= 7.0.3.1)
|
16
|
+
activerecord-nulldb-adapter (0.8.0)
|
17
|
+
activerecord (>= 5.2.0, < 7.1)
|
18
|
+
activesupport (7.0.3.1)
|
23
19
|
concurrent-ruby (~> 1.0, >= 1.0.2)
|
24
20
|
i18n (>= 1.6, < 2)
|
25
21
|
minitest (>= 5.1)
|
26
22
|
tzinfo (~> 2.0)
|
27
|
-
appraisal (2.
|
23
|
+
appraisal (2.4.1)
|
28
24
|
bundler
|
29
25
|
rake
|
30
26
|
thor (>= 0.14.0)
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
diff-lcs (1.
|
36
|
-
i18n (1.
|
27
|
+
concurrent-ruby (1.1.10)
|
28
|
+
debug (1.6.1)
|
29
|
+
irb (>= 1.3.6)
|
30
|
+
reline (>= 0.3.1)
|
31
|
+
diff-lcs (1.5.0)
|
32
|
+
i18n (1.12.0)
|
37
33
|
concurrent-ruby (~> 1.0)
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
rspec-
|
48
|
-
|
34
|
+
io-console (0.5.11)
|
35
|
+
irb (1.4.1)
|
36
|
+
reline (>= 0.3.0)
|
37
|
+
minitest (5.16.2)
|
38
|
+
rake (13.0.6)
|
39
|
+
reline (0.3.1)
|
40
|
+
io-console (~> 0.5)
|
41
|
+
rspec (3.11.0)
|
42
|
+
rspec-core (~> 3.11.0)
|
43
|
+
rspec-expectations (~> 3.11.0)
|
44
|
+
rspec-mocks (~> 3.11.0)
|
45
|
+
rspec-core (3.11.0)
|
46
|
+
rspec-support (~> 3.11.0)
|
47
|
+
rspec-expectations (3.11.0)
|
49
48
|
diff-lcs (>= 1.2.0, < 2.0)
|
50
|
-
rspec-support (~> 3.
|
51
|
-
rspec-mocks (3.
|
49
|
+
rspec-support (~> 3.11.0)
|
50
|
+
rspec-mocks (3.11.1)
|
52
51
|
diff-lcs (>= 1.2.0, < 2.0)
|
53
|
-
rspec-support (~> 3.
|
54
|
-
rspec-support (3.
|
55
|
-
thor (1.
|
56
|
-
tzinfo (2.0.
|
52
|
+
rspec-support (~> 3.11.0)
|
53
|
+
rspec-support (3.11.0)
|
54
|
+
thor (1.2.1)
|
55
|
+
tzinfo (2.0.5)
|
57
56
|
concurrent-ruby (~> 1.0)
|
58
57
|
|
59
58
|
PLATFORMS
|
@@ -63,35 +62,10 @@ DEPENDENCIES
|
|
63
62
|
activerecord (~> 7.0.0)
|
64
63
|
activerecord-nulldb-adapter
|
65
64
|
appraisal
|
66
|
-
|
65
|
+
debug
|
67
66
|
rake
|
68
67
|
rspec
|
69
68
|
stator!
|
70
69
|
|
71
|
-
CHECKSUMS
|
72
|
-
activemodel (7.0.8.7) sha256=f13b04bb055c1e85b965ce40b0a2e671b8d97835083597bc7fbc04cde0f40a83
|
73
|
-
activerecord (7.0.8.7) sha256=f94fc8510e58a18e462c5ee8862c9be75e2bfad0688e8d022b86a6e05df2a45a
|
74
|
-
activerecord-nulldb-adapter (1.1.1) sha256=034c91106183b954b072fba14c2786adf1a2b9e852ce04f85f823afaf03e9820
|
75
|
-
activesupport (7.0.8.7) sha256=df4702375de924aae81709c831605317c5417f0bd9e502a0373ff84a067204ff
|
76
|
-
appraisal (2.5.0) sha256=36989221be127913b0dba8d114da2001e6b2dceea7bd4951200eaba764eed3ce
|
77
|
-
base64 (0.2.0) sha256=0f25e9b21a02a0cc0cea8ef92b2041035d39350946e8789c562b2d1a3da01507
|
78
|
-
benchmark (0.4.0) sha256=0f12f8c495545e3710c3e4f0480f63f06b4c842cc94cec7f33a956f5180e874a
|
79
|
-
bigdecimal (3.1.9) sha256=2ffc742031521ad69c2dfc815a98e426a230a3d22aeac1995826a75dabfad8cc
|
80
|
-
concurrent-ruby (1.3.4) sha256=d4aa926339b0a86b5b5054a0a8c580163e6f5dcbdfd0f4bb916b1a2570731c32
|
81
|
-
diff-lcs (1.6.1) sha256=12a5a83f3e37a8e2f4427268e305914d5f1879f22b4e73bb1a09f76a3dd86cd4
|
82
|
-
i18n (1.14.7) sha256=ceba573f8138ff2c0915427f1fc5bdf4aa3ab8ae88c8ce255eb3ecf0a11a5d0f
|
83
|
-
logger (1.7.0) sha256=196edec7cc44b66cfb40f9755ce11b392f21f7967696af15d274dde7edff0203
|
84
|
-
minitest (5.25.5) sha256=391b6c6cb43a4802bfb7c93af1ebe2ac66a210293f4a3fb7db36f2fc7dc2c756
|
85
|
-
mutex_m (0.3.0) sha256=cfcb04ac16b69c4813777022fdceda24e9f798e48092a2b817eb4c0a782b0751
|
86
|
-
rake (13.2.1) sha256=46cb38dae65d7d74b6020a4ac9d48afed8eb8149c040eccf0523bec91907059d
|
87
|
-
rspec (3.13.0) sha256=d490914ac1d5a5a64a0e1400c1d54ddd2a501324d703b8cfe83f458337bab993
|
88
|
-
rspec-core (3.13.3) sha256=25136507f4f9cf2e8977a2851e64e438b4331646054e345998714108745cdfe4
|
89
|
-
rspec-expectations (3.13.3) sha256=0e6b5af59b900147698ea0ff80456c4f2e69cac4394fbd392fbd1ca561f66c58
|
90
|
-
rspec-mocks (3.13.2) sha256=2327335def0e1665325a9b617e3af9ae20272741d80ac550336309a7c59abdef
|
91
|
-
rspec-support (3.13.2) sha256=cea3a2463fd9b84b9dcc9685efd80ea701aa8f7b3decb3b3ce795ed67737dbec
|
92
|
-
stator (0.8.0)
|
93
|
-
thor (1.3.2) sha256=eef0293b9e24158ccad7ab383ae83534b7ad4ed99c09f96f1a6b036550abbeda
|
94
|
-
tzinfo (2.0.6) sha256=8daf828cc77bcf7d63b0e3bdb6caa47e2272dcfaf4fbfe46f8c3a9df087a829b
|
95
|
-
|
96
70
|
BUNDLED WITH
|
97
|
-
2.
|
71
|
+
2.3.16
|
data/lib/stator/alias.rb
CHANGED
@@ -1,11 +1,13 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module Stator
|
2
4
|
class Alias
|
5
|
+
attr_reader :machine, :name, :namespace, :attr_name, :states, :not, :opposite_args, :constant, :scope
|
3
6
|
|
4
7
|
def initialize(machine, name, options = {})
|
5
8
|
@machine = machine
|
6
9
|
@name = name
|
7
|
-
@namespace =
|
8
|
-
@full_name = [@namespace, @name].compact.join('_')
|
10
|
+
@namespace = machine.namespace
|
9
11
|
@states = []
|
10
12
|
@not = false
|
11
13
|
@opposite = nil
|
@@ -13,8 +15,12 @@ module Stator
|
|
13
15
|
@scope = options[:scope]
|
14
16
|
end
|
15
17
|
|
18
|
+
def attr_name
|
19
|
+
@attr_name ||= generate_attr_name
|
20
|
+
end
|
21
|
+
|
16
22
|
def is(*args)
|
17
|
-
@states |= args.map(&:
|
23
|
+
@states |= args.map(&:to_sym)
|
18
24
|
end
|
19
25
|
|
20
26
|
def is_not(*args)
|
@@ -22,60 +28,75 @@ module Stator
|
|
22
28
|
is(*args)
|
23
29
|
end
|
24
30
|
|
31
|
+
alias not? not
|
32
|
+
|
25
33
|
def opposite(*args)
|
26
|
-
|
34
|
+
# set the incoming args for opposite as opposite
|
35
|
+
@opposite_args = args
|
27
36
|
end
|
28
37
|
|
29
38
|
def evaluate
|
30
39
|
generate_methods
|
31
40
|
|
32
|
-
if
|
33
|
-
op = @machine.state_alias(*@opposite)
|
41
|
+
return if opposite_args.blank?
|
34
42
|
|
35
|
-
|
36
|
-
|
37
|
-
|
43
|
+
# this will generate the alias for the opposite
|
44
|
+
op = machine.state_alias(*opposite_args)
|
45
|
+
|
46
|
+
op.is(*states) if not?
|
47
|
+
op.is_not(*states) unless not?
|
38
48
|
end
|
39
49
|
|
40
|
-
|
50
|
+
private
|
51
|
+
|
52
|
+
def inverse_states
|
53
|
+
(machine.states - states).map(&:to_sym)
|
54
|
+
end
|
41
55
|
|
42
56
|
def inferred_constant_name
|
43
|
-
[
|
57
|
+
[attr_name.upcase, machine.field.to_s.pluralize.upcase].join('_')
|
58
|
+
end
|
59
|
+
|
60
|
+
def generate_attr_name
|
61
|
+
if namespace == Stator.default_namespace
|
62
|
+
name
|
63
|
+
else
|
64
|
+
[namespace, name].compact.join('_').to_sym
|
65
|
+
end
|
44
66
|
end
|
45
67
|
|
46
68
|
def generate_methods
|
69
|
+
expected_states = (not? ? inverse_states : states)
|
47
70
|
|
48
|
-
|
71
|
+
if scope
|
72
|
+
name = (scope == true ? attr_name : scope)
|
49
73
|
|
50
|
-
|
51
|
-
|
52
|
-
@machine.klass.class_eval <<-EV, __FILE__, __LINE__ + 1
|
53
|
-
scope #{name.inspect}, lambda {
|
54
|
-
where(_stator(#{@namespace.inspect}).field => #{(@not ? not_states : @states).inspect})
|
55
|
-
}
|
74
|
+
machine.klass.class_eval <<-EV, __FILE__, __LINE__ + 1
|
75
|
+
scope :#{name}, -> { where(_stator(#{namespace.inspect}).field => #{expected_states}) }
|
56
76
|
EV
|
57
77
|
end
|
58
78
|
|
59
|
-
if
|
60
|
-
name =
|
61
|
-
|
62
|
-
|
63
|
-
|
79
|
+
if constant
|
80
|
+
name = (constant == true ? inferred_constant_name : constant.to_s.upcase)
|
81
|
+
|
82
|
+
if not?
|
83
|
+
machine.klass.class_eval <<-EV, __FILE__, __LINE__ + 1
|
84
|
+
#{name} = #{inverse_states}.freeze
|
64
85
|
EV
|
65
86
|
else
|
66
|
-
|
67
|
-
#{name} = #{
|
87
|
+
machine.klass.class_eval <<-EV, __FILE__, __LINE__ + 1
|
88
|
+
#{name} = #{states}.freeze
|
68
89
|
EV
|
69
90
|
end
|
70
91
|
end
|
71
92
|
|
72
|
-
|
73
|
-
def #{
|
74
|
-
integration =
|
75
|
-
|
93
|
+
machine.klass.class_eval <<-EV, __FILE__, __LINE__ + 1
|
94
|
+
def #{attr_name}?
|
95
|
+
integration = _stator_integration(:#{namespace})
|
96
|
+
|
97
|
+
#{expected_states}.include?(integration.state.to_sym)
|
76
98
|
end
|
77
99
|
EV
|
78
100
|
end
|
79
|
-
|
80
101
|
end
|
81
102
|
end
|
data/lib/stator/integration.rb
CHANGED
@@ -2,48 +2,48 @@
|
|
2
2
|
|
3
3
|
module Stator
|
4
4
|
class Integration
|
5
|
+
delegate :states, to: :machine
|
6
|
+
delegate :transitions, to: :machine
|
7
|
+
delegate :namespace, to: :machine
|
5
8
|
|
6
|
-
|
7
|
-
delegate :transitions, to: :@machine
|
8
|
-
delegate :namespace, to: :@machine
|
9
|
-
|
10
|
-
attr_reader :skip_validations
|
11
|
-
attr_reader :skip_transition_tracking
|
9
|
+
attr_reader :skip_validations, :skip_transition_tracking, :record, :machine
|
12
10
|
|
13
11
|
def initialize(machine, record)
|
14
12
|
@machine = machine
|
15
13
|
@record = record
|
14
|
+
@skip_transition_tracking = false
|
16
15
|
end
|
17
16
|
|
18
17
|
def state=(new_value)
|
19
|
-
|
18
|
+
record.send("#{machine.field}=", new_value)
|
20
19
|
end
|
21
20
|
|
22
21
|
def state
|
23
|
-
|
22
|
+
record.send(machine.field)&.to_sym
|
24
23
|
end
|
25
24
|
|
26
25
|
def state_was(use_previous = false)
|
27
26
|
if use_previous
|
28
|
-
|
27
|
+
record.previous_changes[machine.field].try(:[], 0).to_sym
|
29
28
|
else
|
30
|
-
|
29
|
+
record.send("#{@machine.field}_was")
|
31
30
|
end
|
32
31
|
end
|
33
32
|
|
34
33
|
def state_by?(state, time)
|
35
|
-
field_name = "#{state}_#{
|
36
|
-
return false unless
|
37
|
-
return false if
|
34
|
+
field_name = "#{state}_#{machine.field}_at"
|
35
|
+
return false unless record.respond_to?(field_name)
|
36
|
+
return false if record.send(field_name).nil?
|
38
37
|
return true if time.nil?
|
39
|
-
|
38
|
+
|
39
|
+
record.send(field_name) <= time
|
40
40
|
end
|
41
41
|
|
42
42
|
def state_changed?(use_previous = false)
|
43
43
|
if use_previous
|
44
|
-
|
44
|
+
!!record.previous_changes[machine.field.to_s]
|
45
45
|
else
|
46
|
-
|
46
|
+
record.send("#{machine.field}_changed?")
|
47
47
|
end
|
48
48
|
end
|
49
49
|
|
@@ -51,23 +51,20 @@ module Stator
|
|
51
51
|
return unless state_changed?
|
52
52
|
return if skip_validations
|
53
53
|
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
if @record.new_record?
|
58
|
-
invalid_state! unless @machine.matching_transition(::Stator::Transition::ANY, is)
|
54
|
+
if record.new_record?
|
55
|
+
invalid_state! unless machine.matching_transition(Stator::ANY, state)
|
59
56
|
else
|
60
|
-
invalid_transition!(
|
57
|
+
invalid_transition!(state_was, state) unless machine.matching_transition(state_was, state)
|
61
58
|
end
|
62
59
|
end
|
63
60
|
|
64
61
|
# TODO: i18n
|
65
62
|
def invalid_state!
|
66
|
-
|
63
|
+
record.errors.add(machine.field, 'is not a valid state')
|
67
64
|
end
|
68
65
|
|
69
66
|
def invalid_transition!(was, is)
|
70
|
-
|
67
|
+
record.errors.add(machine.field, "cannot transition to #{is} from #{was}")
|
71
68
|
end
|
72
69
|
|
73
70
|
def track_transition
|
@@ -83,7 +80,7 @@ module Stator
|
|
83
80
|
state = state.to_s
|
84
81
|
t = t.to_time
|
85
82
|
|
86
|
-
state_at =
|
83
|
+
state_at = record.send("#{state}_#{machine.field}_at")
|
87
84
|
|
88
85
|
# if we've never been in the state, the answer is no
|
89
86
|
return false if state_at.nil?
|
@@ -91,20 +88,18 @@ module Stator
|
|
91
88
|
# if we came into this state later in life, the answer is no
|
92
89
|
return false if state_at > t
|
93
90
|
|
94
|
-
all_states =
|
91
|
+
all_states = machine.states.reverse
|
95
92
|
|
96
93
|
# grab all the states and their timestamps that occur on or after state_at and on or before the time in question
|
97
|
-
later_states = all_states.
|
94
|
+
later_states = all_states.filter_map do |s|
|
98
95
|
next if state == s
|
99
96
|
|
100
|
-
at =
|
97
|
+
at = record.send("#{s}_#{machine.field}_at")
|
101
98
|
|
102
|
-
next if at.nil?
|
103
|
-
next if at < state_at
|
104
|
-
next if at > t
|
99
|
+
next if at.nil? || at < state_at || at > t
|
105
100
|
|
106
101
|
{ state: s, at: at }
|
107
|
-
end
|
102
|
+
end
|
108
103
|
|
109
104
|
# if there were no states on or after the state_at, the answer is yes
|
110
105
|
return true if later_states.empty?
|
@@ -115,53 +110,51 @@ module Stator
|
|
115
110
|
later_states = later_groups[later_group_key]
|
116
111
|
|
117
112
|
# if the lowest timestamp is the same as the state's timestamp, evaluate based on state index
|
118
|
-
if later_states[0][:at] == state_at
|
119
|
-
return all_states.index(state) < all_states.index(later_states[0][:state])
|
120
|
-
end
|
113
|
+
return all_states.index(state) < all_states.index(later_states[0][:state]) if later_states[0][:at] == state_at
|
121
114
|
|
122
115
|
false
|
123
116
|
end
|
124
117
|
|
125
118
|
def likely_state_at(t)
|
126
|
-
|
119
|
+
machine.states.reverse.detect { |s| in_state_at?(s, t) }
|
127
120
|
end
|
128
121
|
|
129
122
|
def without_validation
|
130
|
-
was =
|
123
|
+
was = skip_validations
|
131
124
|
@skip_validations = true
|
132
|
-
yield
|
125
|
+
yield record
|
133
126
|
ensure
|
134
127
|
@skip_validations = was
|
135
128
|
end
|
136
129
|
|
137
130
|
def without_transition_tracking
|
138
|
-
was =
|
131
|
+
was = skip_transition_tracking
|
139
132
|
@skip_transition_tracking = true
|
140
|
-
yield
|
133
|
+
yield record
|
141
134
|
ensure
|
142
135
|
@skip_transition_tracking = was
|
143
136
|
end
|
144
137
|
|
145
|
-
|
138
|
+
private
|
146
139
|
|
147
140
|
def attempt_to_track_state(state_to_track)
|
148
141
|
return unless state_to_track
|
149
142
|
|
150
|
-
_attempt_to_track_change("#{state_to_track}_#{
|
143
|
+
_attempt_to_track_change("#{state_to_track}_#{machine.field}_at")
|
151
144
|
end
|
152
145
|
|
153
146
|
def attempt_to_track_state_changed_timestamp
|
154
|
-
_attempt_to_track_change("#{
|
147
|
+
_attempt_to_track_change("#{machine.field}_changed_at")
|
155
148
|
end
|
156
149
|
|
157
150
|
def _attempt_to_track_change(field_name)
|
158
|
-
return unless
|
159
|
-
return unless
|
160
|
-
return unless
|
161
|
-
return if @record.will_save_change_to_attribute?(field_name)
|
151
|
+
return unless record.respond_to?(field_name)
|
152
|
+
return unless record.respond_to?("#{field_name}=")
|
153
|
+
return unless record.send(field_name.to_s).nil? || state_changed?
|
162
154
|
|
163
|
-
|
164
|
-
end
|
155
|
+
return if record.send("#{field_name}_changed?")
|
165
156
|
|
157
|
+
record.send("#{field_name}=", (Time.zone || Time).now)
|
158
|
+
end
|
166
159
|
end
|
167
160
|
end
|