statefully 0.1.1 → 0.1.2
Sign up to get free protection for your applications and to get access to all the features.
- 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
|