statefully 0.1.1 → 0.1.2
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/lib/statefully/state.rb +30 -13
- data/spec/spec_helper.rb +7 -0
- data/spec/state_spec.rb +45 -18
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 1962b427e73969e2c630c8fe1c22a0f55e7f2fc4
|
4
|
+
data.tar.gz: 3f5b532398769ecdaeaeb897368230022d22825a
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: e0189ab5e902b110f36e6189d7c81b88a8b53a99c2015bec935cf54cafb2fcc71747810247297acd609b0d1517a6440b89f821b0d4f853d18632768470400358
|
7
|
+
data.tar.gz: df202b95fe53c904ebb4d2235a759622e6583ee674eca303274b1685f91782af247f82b50b1ffe47fb33d25618d7da3d684c41a99c8906a311f178442edc034a
|
data/lib/statefully/state.rb
CHANGED
@@ -29,12 +29,16 @@ module Statefully
|
|
29
29
|
!success?
|
30
30
|
end
|
31
31
|
|
32
|
+
def finished?
|
33
|
+
false
|
34
|
+
end
|
35
|
+
|
32
36
|
def resolve
|
33
37
|
self
|
34
38
|
end
|
35
39
|
|
36
40
|
def inspect
|
37
|
-
|
41
|
+
_inspect_details({})
|
38
42
|
end
|
39
43
|
|
40
44
|
private
|
@@ -47,7 +51,7 @@ module Statefully
|
|
47
51
|
end
|
48
52
|
private_class_method :new
|
49
53
|
|
50
|
-
def
|
54
|
+
def _inspect_details(extras)
|
51
55
|
details = [self.class.name]
|
52
56
|
fields = _members.merge(extras)
|
53
57
|
details << Inspect.from_fields(fields) unless fields.empty?
|
@@ -74,6 +78,15 @@ module Statefully
|
|
74
78
|
key?(name.to_sym) || %w[? !].any?(&str_name.method(:end_with?)) || super
|
75
79
|
end
|
76
80
|
|
81
|
+
class Missing < RuntimeError
|
82
|
+
attr_reader :field
|
83
|
+
|
84
|
+
def initialize(field)
|
85
|
+
@field = field
|
86
|
+
super("field '#{field}' missing from state")
|
87
|
+
end
|
88
|
+
end # class Missing
|
89
|
+
|
77
90
|
class None < State
|
78
91
|
include Singleton
|
79
92
|
|
@@ -93,15 +106,16 @@ module Statefully
|
|
93
106
|
# Success is a not-yet failed State.
|
94
107
|
class Success < State
|
95
108
|
def succeed(**values)
|
96
|
-
self
|
97
|
-
.class
|
98
|
-
.send(:new, _members.merge(values).freeze, previous: self)
|
99
|
-
.freeze
|
109
|
+
self.class.send(:new, _members.merge(values).freeze, previous: self)
|
100
110
|
end
|
101
111
|
|
102
112
|
def fail(error)
|
103
113
|
Failure.send(:new, _members, error, previous: self).freeze
|
104
114
|
end
|
115
|
+
|
116
|
+
def finish
|
117
|
+
Finished.send(:new, _members, previous: self).freeze
|
118
|
+
end
|
105
119
|
end # class Success
|
106
120
|
private_constant :Success
|
107
121
|
|
@@ -127,18 +141,21 @@ module Statefully
|
|
127
141
|
end
|
128
142
|
|
129
143
|
def inspect
|
130
|
-
|
144
|
+
_inspect_details(error: error.inspect)
|
131
145
|
end
|
132
146
|
end # class Failure
|
147
|
+
private_constant :Failure
|
133
148
|
|
134
|
-
class
|
135
|
-
|
149
|
+
class Finished < State
|
150
|
+
def diff
|
151
|
+
:finished
|
152
|
+
end
|
136
153
|
|
137
|
-
def
|
138
|
-
|
139
|
-
super("field '#{field}' missing from state")
|
154
|
+
def finished?
|
155
|
+
true
|
140
156
|
end
|
141
|
-
end # class
|
157
|
+
end # class Finished
|
158
|
+
private_constant :Finished
|
142
159
|
|
143
160
|
module Inspect
|
144
161
|
def from_fields(input)
|
data/spec/spec_helper.rb
CHANGED
data/spec/state_spec.rb
CHANGED
@@ -33,21 +33,29 @@ module Statefully
|
|
33
33
|
it { expect(subject.resolve).to eq subject }
|
34
34
|
it { expect(subject).to be_success }
|
35
35
|
it { expect(subject).not_to be_failure }
|
36
|
+
it { expect(subject).not_to be_finished }
|
36
37
|
end # describe 'trivial readers'
|
37
38
|
|
39
|
+
shared_examples 'successful_state' do
|
40
|
+
it { expect(next_state).to be_success }
|
41
|
+
it { expect(next_state.old_key).to eq val }
|
42
|
+
|
43
|
+
it { expect(next_state.previous).to eq subject }
|
44
|
+
it { expect(next_state.resolve).to eq next_state }
|
45
|
+
end # shared_examples 'successful_state'
|
46
|
+
|
38
47
|
describe '#succeed' do
|
39
|
-
let(:new_val)
|
40
|
-
let(:
|
48
|
+
let(:new_val) { 'new_val' }
|
49
|
+
let(:next_state) { subject.succeed(new_key: new_val) }
|
50
|
+
|
51
|
+
it_behaves_like 'successful_state'
|
41
52
|
|
42
|
-
it { expect(
|
43
|
-
it { expect(
|
44
|
-
it { expect(
|
45
|
-
it { expect(succeeded.keys).to eq %i[old_key new_key] }
|
46
|
-
it { expect(succeeded.previous).to eq subject }
|
47
|
-
it { expect(succeeded.resolve).to eq succeeded }
|
53
|
+
it { expect(next_state).not_to be_finished }
|
54
|
+
it { expect(next_state.new_key).to eq new_val }
|
55
|
+
it { expect(next_state.keys).to eq %i[old_key new_key] }
|
48
56
|
|
49
57
|
context 'with history' do
|
50
|
-
let(:history) {
|
58
|
+
let(:history) { next_state.history }
|
51
59
|
|
52
60
|
it { expect(history.size).to eq 2 }
|
53
61
|
it { expect(history.first.added).to include :new_key }
|
@@ -56,28 +64,47 @@ module Statefully
|
|
56
64
|
end # describe '#succeed'
|
57
65
|
|
58
66
|
describe '#fail' do
|
59
|
-
let(:error)
|
60
|
-
let(:
|
67
|
+
let(:error) { RuntimeError.new('snakes on a plane') }
|
68
|
+
let(:next_state) { subject.fail(error) }
|
61
69
|
|
62
|
-
it { expect(
|
63
|
-
it { expect(
|
64
|
-
it { expect(
|
65
|
-
it { expect(
|
66
|
-
it { expect(
|
70
|
+
it { expect(next_state).not_to be_success }
|
71
|
+
it { expect(next_state).to be_failure }
|
72
|
+
it { expect(next_state).not_to be_finished }
|
73
|
+
it { expect(subject).not_to be_finished }
|
74
|
+
it { expect(next_state.old_key).to eq val }
|
75
|
+
it { expect(next_state.previous).to eq subject }
|
76
|
+
it { expect(next_state.error).to eq error }
|
67
77
|
|
68
78
|
it 'raises passed error on #resolve' do
|
69
|
-
expect {
|
79
|
+
expect { next_state.resolve }.to raise_error do |err|
|
70
80
|
expect(err).to eq error
|
71
81
|
end
|
72
82
|
end
|
73
83
|
|
74
84
|
context 'with history' do
|
75
|
-
let(:history) {
|
85
|
+
let(:history) { next_state.history }
|
76
86
|
|
77
87
|
it { expect(history.size).to eq 2 }
|
78
88
|
it { expect(history.first).to eq error }
|
79
89
|
it { expect(history.last.added).to include :old_key }
|
80
90
|
end # context 'with history'
|
81
91
|
end # describe '#fail'
|
92
|
+
|
93
|
+
describe '#finish' do
|
94
|
+
let(:new_val) { 'new_val' }
|
95
|
+
let(:next_state) { subject.finish }
|
96
|
+
|
97
|
+
it_behaves_like 'successful_state'
|
98
|
+
|
99
|
+
it { expect(next_state).to be_finished }
|
100
|
+
|
101
|
+
context 'with history' do
|
102
|
+
let(:history) { next_state.history }
|
103
|
+
|
104
|
+
it { expect(history.size).to eq 2 }
|
105
|
+
it { expect(history.first).to eq :finished }
|
106
|
+
it { expect(history.last.added).to include :old_key }
|
107
|
+
end # context 'with history'
|
108
|
+
end # describe '#finish'
|
82
109
|
end # describe 'State::Success'
|
83
110
|
end # module Statefully
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: statefully
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Marcin Wyszynski
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2017-05-
|
11
|
+
date: 2017-05-21 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|