statefully 0.1.6 → 0.1.7
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/statefully/change.rb +2 -2
- data/lib/statefully/diff.rb +9 -9
- data/lib/statefully/errors.rb +4 -3
- data/lib/statefully/inspect.rb +2 -2
- data/lib/statefully/state.rb +10 -7
- data/lib/statefully/version.rb +2 -2
- data/spec/diff_spec.rb +14 -14
- data/spec/errors_spec.rb +3 -3
- data/spec/state_spec.rb +33 -33
- metadata +3 -23
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: ab676bd0fdc9e9d6b17d8c606aa381e9aeab8cac
|
4
|
+
data.tar.gz: 11c77ad8e395dac8b413606ce8e7698b4482c27b
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: a6dcbb610b68d77357d1f4a015cadb5c33430b763ea244bacc6bf2d9748356bb7576ec5154b6c3c4840248bac1df85b1f45134ad11c1e99c011510fd8cd2e024
|
7
|
+
data.tar.gz: '0543961fa3864e71e1c647c8f1d1176ee1ad6bdfd420dd8a2336358f8f2e65b3c5a4c6458815a85c64c10f82aa4c14919a5a5b5de4d4d456bfa0d847eec9cc92'
|
data/lib/statefully/change.rb
CHANGED
data/lib/statefully/diff.rb
CHANGED
@@ -194,7 +194,7 @@ module Statefully
|
|
194
194
|
def inspect_changed
|
195
195
|
changed.empty? ? nil : "changed=#{Inspect.from_hash(changed)}"
|
196
196
|
end
|
197
|
-
end
|
197
|
+
end
|
198
198
|
|
199
199
|
module SingletonInspect
|
200
200
|
# Human-readable representation of the {Diff} singleton
|
@@ -204,7 +204,7 @@ module Statefully
|
|
204
204
|
def inspect
|
205
205
|
"#<#{self.class.name}>"
|
206
206
|
end
|
207
|
-
end
|
207
|
+
end
|
208
208
|
private_constant :SingletonInspect
|
209
209
|
|
210
210
|
# {Created} represents a difference between a null and non-null {State}.
|
@@ -222,13 +222,13 @@ module Statefully
|
|
222
222
|
def created?
|
223
223
|
true
|
224
224
|
end
|
225
|
-
end
|
225
|
+
end
|
226
226
|
|
227
227
|
# {Unchanged} represents a lack of difference between two {State}s.
|
228
228
|
class Unchanged < Diff
|
229
229
|
include Singleton
|
230
230
|
include SingletonInspect
|
231
|
-
end
|
231
|
+
end
|
232
232
|
|
233
233
|
# {Failed} represents a difference between a succesful and failed {State}.
|
234
234
|
class Failed < Diff
|
@@ -262,13 +262,13 @@ module Statefully
|
|
262
262
|
def inspect
|
263
263
|
"#<#{self.class.name} error=#{error.inspect}>"
|
264
264
|
end
|
265
|
-
end
|
265
|
+
end
|
266
266
|
|
267
267
|
# {Failed} represents a difference between a succesful and finished {State}.
|
268
268
|
class Finished < Diff
|
269
269
|
include Singleton
|
270
270
|
include SingletonInspect
|
271
|
-
end
|
271
|
+
end
|
272
272
|
|
273
273
|
class Builder
|
274
274
|
# Constructor for the {Builder} object
|
@@ -350,7 +350,7 @@ module Statefully
|
|
350
350
|
def previous_keys
|
351
351
|
Set.new(@previous.keys)
|
352
352
|
end
|
353
|
-
end
|
353
|
+
end
|
354
354
|
private_constant :Builder
|
355
|
-
end
|
356
|
-
end
|
355
|
+
end
|
356
|
+
end
|
data/lib/statefully/errors.rb
CHANGED
data/lib/statefully/inspect.rb
CHANGED
data/lib/statefully/state.rb
CHANGED
@@ -1,4 +1,5 @@
|
|
1
1
|
require 'forwardable'
|
2
|
+
require 'securerandom'
|
2
3
|
require 'singleton'
|
3
4
|
|
4
5
|
# rubocop:disable Metrics/LineLength
|
@@ -66,7 +67,8 @@ module Statefully
|
|
66
67
|
# Statefully::State.create(key: 'val')
|
67
68
|
# => #<Statefully::State::Success key="val">
|
68
69
|
def self.create(**values)
|
69
|
-
|
70
|
+
base = { correlation_id: SecureRandom.uuid }
|
71
|
+
Success.send(:new, base.merge(values), previous: None.instance).freeze
|
70
72
|
end
|
71
73
|
|
72
74
|
# Return a {Diff} between current and previous {State}
|
@@ -322,7 +324,7 @@ module Statefully
|
|
322
324
|
@_members = {}.freeze
|
323
325
|
@previous = self
|
324
326
|
end
|
325
|
-
end
|
327
|
+
end
|
326
328
|
|
327
329
|
# {Success} is a not-yet failed {State}.
|
328
330
|
class Success < State
|
@@ -362,7 +364,7 @@ module Statefully
|
|
362
364
|
def finish
|
363
365
|
Finished.send(:new, _members, previous: self).freeze
|
364
366
|
end
|
365
|
-
end
|
367
|
+
end
|
366
368
|
|
367
369
|
# {Failure} is a failed {State}.
|
368
370
|
class Failure < State
|
@@ -444,7 +446,7 @@ module Statefully
|
|
444
446
|
def inspect
|
445
447
|
_inspect_details(error: error.inspect)
|
446
448
|
end
|
447
|
-
end
|
449
|
+
end
|
448
450
|
|
449
451
|
# {Finished} state is a state which is successful, but should not be
|
450
452
|
# processed any further. This could be useful for things like early returns.
|
@@ -476,6 +478,7 @@ module Statefully
|
|
476
478
|
def finished?
|
477
479
|
true
|
478
480
|
end
|
479
|
-
end
|
480
|
-
end
|
481
|
-
end
|
481
|
+
end
|
482
|
+
end
|
483
|
+
end
|
484
|
+
# rubocop:enable Metrics/LineLength
|
data/lib/statefully/version.rb
CHANGED
@@ -1,3 +1,3 @@
|
|
1
1
|
module Statefully
|
2
|
-
VERSION = '0.1.
|
3
|
-
end
|
2
|
+
VERSION = '0.1.7'.freeze
|
3
|
+
end
|
data/spec/diff_spec.rb
CHANGED
@@ -9,31 +9,31 @@ module Statefully
|
|
9
9
|
let(:previous) { State::None.instance }
|
10
10
|
|
11
11
|
it { expect(diff).to be_created }
|
12
|
-
end
|
12
|
+
end
|
13
13
|
|
14
14
|
context 'when key added' do
|
15
|
-
let(:current) { State.create(key: 'val') }
|
16
15
|
let(:previous) { State.create }
|
16
|
+
let(:current) { previous.succeed(key: 'val') }
|
17
17
|
|
18
18
|
it { expect(diff).not_to be_empty }
|
19
19
|
it { expect(diff).not_to be_created }
|
20
20
|
it { expect(diff.added).to have_key(:key) }
|
21
|
-
it { expect(diff.
|
21
|
+
it { expect(diff).to be_added(:key) }
|
22
22
|
it { expect(diff.added.fetch(:key)).to eq 'val' }
|
23
23
|
it { expect(diff.changed).to be_empty }
|
24
24
|
|
25
25
|
it { expect(diff.inspect).to start_with '#<Statefully::Diff::Changed' }
|
26
26
|
it { expect(diff.inspect).to include 'added={key: "val"}>' }
|
27
|
-
end
|
27
|
+
end
|
28
28
|
|
29
29
|
context 'when key changed' do
|
30
|
-
let(:current) { State.create(key: 'new') }
|
31
30
|
let(:previous) { State.create(key: 'old') }
|
31
|
+
let(:current) { previous.succeed(key: 'new') }
|
32
32
|
|
33
33
|
it { expect(diff).not_to be_empty }
|
34
34
|
it { expect(diff.added).to be_empty }
|
35
35
|
it { expect(diff.changed).to have_key(:key) }
|
36
|
-
it { expect(diff.
|
36
|
+
it { expect(diff).to be_changed(:key) }
|
37
37
|
|
38
38
|
it { expect(diff.inspect).to include 'changed=' }
|
39
39
|
|
@@ -42,8 +42,8 @@ module Statefully
|
|
42
42
|
|
43
43
|
it { expect(change.current).to eq 'new' }
|
44
44
|
it { expect(change.previous).to eq 'old' }
|
45
|
-
end
|
46
|
-
end
|
45
|
+
end
|
46
|
+
end
|
47
47
|
|
48
48
|
context 'when nothing changed' do
|
49
49
|
let(:current) { State.create(key: 'key') }
|
@@ -51,13 +51,13 @@ module Statefully
|
|
51
51
|
|
52
52
|
it { expect(diff).to be_empty }
|
53
53
|
it { expect(diff.inspect).to eq '#<Statefully::Diff::Unchanged>' }
|
54
|
-
end
|
54
|
+
end
|
55
55
|
|
56
56
|
shared_examples 'diff_is_empty' do
|
57
57
|
it { expect(diff).to be_empty }
|
58
58
|
it { expect(diff.added).to be_empty }
|
59
59
|
it { expect(diff.changed).to be_empty }
|
60
|
-
end
|
60
|
+
end
|
61
61
|
|
62
62
|
context 'when failed' do
|
63
63
|
let(:error) { RuntimeError.new('boo!') }
|
@@ -70,7 +70,7 @@ module Statefully
|
|
70
70
|
|
71
71
|
it { expect(diff.inspect).to start_with '#<Statefully::Diff::Failed' }
|
72
72
|
it { expect(diff.inspect).to include 'error=#<RuntimeError: boo!>' }
|
73
|
-
end
|
73
|
+
end
|
74
74
|
|
75
75
|
context 'when finished' do
|
76
76
|
let(:previous) { State.create }
|
@@ -79,6 +79,6 @@ module Statefully
|
|
79
79
|
it_behaves_like 'diff_is_empty'
|
80
80
|
|
81
81
|
it { expect(diff.inspect).to eq '#<Statefully::Diff::Finished>' }
|
82
|
-
end
|
83
|
-
end
|
84
|
-
end
|
82
|
+
end
|
83
|
+
end
|
84
|
+
end
|
data/spec/errors_spec.rb
CHANGED
data/spec/state_spec.rb
CHANGED
@@ -1,5 +1,7 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
|
+
require 'pry'
|
4
|
+
|
3
5
|
module Statefully
|
4
6
|
describe State do
|
5
7
|
describe '.create' do
|
@@ -12,12 +14,12 @@ module Statefully
|
|
12
14
|
|
13
15
|
context 'with diff' do
|
14
16
|
let(:diff) { state.diff }
|
15
|
-
let(:expected) { '#<Statefully::Diff::Created
|
17
|
+
let(:expected) { '#<Statefully::Diff::Created' }
|
16
18
|
|
17
19
|
it { expect(diff).to be_created }
|
18
|
-
it { expect(diff.inspect).to
|
19
|
-
end
|
20
|
-
end
|
20
|
+
it { expect(diff.inspect).to start_with expected }
|
21
|
+
end
|
22
|
+
end
|
21
23
|
|
22
24
|
context 'with keyword arguments' do
|
23
25
|
let(:args) { { key: 'val' } }
|
@@ -27,51 +29,49 @@ module Statefully
|
|
27
29
|
let(:expected) { '#<Statefully::Diff::Created added={key: "val"}>' }
|
28
30
|
|
29
31
|
it { expect(diff).to be_created }
|
30
|
-
it { expect(diff.
|
31
|
-
end
|
32
|
-
end
|
33
|
-
end
|
34
|
-
end
|
32
|
+
it { expect(diff.added).to include args }
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
35
37
|
|
36
38
|
describe 'State::Success' do
|
37
39
|
let(:val) { 'val' }
|
38
40
|
let(:state) { State.create(old_key: val) }
|
39
41
|
|
40
42
|
describe 'methods delegated to the underlying Hash' do
|
41
|
-
it { expect(state.keys).to eq [
|
42
|
-
it { expect(state.
|
43
|
-
it { expect(state.
|
44
|
-
end
|
43
|
+
it { expect(state.keys).to eq %i[correlation_id old_key] }
|
44
|
+
it { expect(state).to be_key(:old_key) }
|
45
|
+
it { expect(state).to(be_any { |_, value| value == val }) }
|
46
|
+
end
|
45
47
|
|
46
48
|
describe "methods dynamically dispatched using 'method_missing'" do
|
47
49
|
it { expect(state.old_key).to eq val }
|
48
|
-
it { expect(state
|
50
|
+
it { expect(state).to be_old_key }
|
49
51
|
it { expect(state.old_key!).to eq val }
|
50
52
|
|
51
53
|
it { expect { state.new_key }.to raise_error NoMethodError }
|
52
|
-
it { expect(state
|
54
|
+
it { expect(state).not_to be_new_key }
|
53
55
|
it { expect { state.new_key! }.to raise_error Errors::StateMissing }
|
54
|
-
end
|
56
|
+
end
|
55
57
|
|
56
58
|
describe 'trivial readers' do
|
57
59
|
it { expect(state.resolve).to eq state }
|
58
60
|
it { expect(state).to be_successful }
|
59
61
|
it { expect(state).not_to be_failed }
|
60
62
|
it { expect(state).not_to be_finished }
|
61
|
-
end
|
63
|
+
end
|
62
64
|
|
63
65
|
describe 'history' do
|
64
66
|
let(:history) { state.history }
|
65
67
|
|
66
68
|
it { expect(history.length).to eq 1 }
|
67
69
|
it { expect(history.first).to be_created }
|
68
|
-
end
|
70
|
+
end
|
69
71
|
|
70
72
|
describe '#inspect' do
|
71
|
-
|
72
|
-
|
73
|
-
it { expect(state.inspect).to eq expected }
|
74
|
-
end # describe '#inspect'
|
73
|
+
it { expect(state.inspect).to include 'old_key="val"' }
|
74
|
+
end
|
75
75
|
|
76
76
|
shared_examples 'successful_state' do
|
77
77
|
it { expect(next_state).to be_successful }
|
@@ -79,7 +79,7 @@ module Statefully
|
|
79
79
|
|
80
80
|
it { expect(next_state.previous).to eq state }
|
81
81
|
it { expect(next_state.resolve).to eq next_state }
|
82
|
-
end
|
82
|
+
end
|
83
83
|
|
84
84
|
describe '#succeed' do
|
85
85
|
let(:new_val) { 'new_val' }
|
@@ -89,7 +89,7 @@ module Statefully
|
|
89
89
|
|
90
90
|
it { expect(next_state).not_to be_finished }
|
91
91
|
it { expect(next_state.new_key).to eq new_val }
|
92
|
-
it { expect(next_state.keys).to eq %i[old_key new_key] }
|
92
|
+
it { expect(next_state.keys).to eq %i[correlation_id old_key new_key] }
|
93
93
|
|
94
94
|
context 'with history' do
|
95
95
|
let(:history) { next_state.history }
|
@@ -98,8 +98,8 @@ module Statefully
|
|
98
98
|
it { expect(history.first).not_to be_created }
|
99
99
|
it { expect(history.first.added).to include :new_key }
|
100
100
|
it { expect(history.last.added).to include :old_key }
|
101
|
-
end
|
102
|
-
end
|
101
|
+
end
|
102
|
+
end
|
103
103
|
|
104
104
|
describe '#fail' do
|
105
105
|
let(:error) { RuntimeError.new('boo!') }
|
@@ -120,7 +120,7 @@ module Statefully
|
|
120
120
|
it { expect(inspect).to start_with '#<Statefully::State::Failure' }
|
121
121
|
it { expect(inspect).to include 'old_key="val"' }
|
122
122
|
it { expect(inspect).to include 'error="#<RuntimeError: boo!>"' }
|
123
|
-
end
|
123
|
+
end
|
124
124
|
|
125
125
|
context 'with history' do
|
126
126
|
let(:history) { next_state.history }
|
@@ -128,8 +128,8 @@ module Statefully
|
|
128
128
|
it { expect(history.size).to eq 2 }
|
129
129
|
it { expect(history.first.error).to eq error }
|
130
130
|
it { expect(history.last.added).to include :old_key }
|
131
|
-
end
|
132
|
-
end
|
131
|
+
end
|
132
|
+
end
|
133
133
|
|
134
134
|
describe '#finish' do
|
135
135
|
let(:new_val) { 'new_val' }
|
@@ -145,7 +145,7 @@ module Statefully
|
|
145
145
|
it { expect(history.size).to eq 2 }
|
146
146
|
it { expect(history.first).to eq Diff::Finished.instance }
|
147
147
|
it { expect(history.last.added).to include :old_key }
|
148
|
-
end
|
149
|
-
end
|
150
|
-
end
|
151
|
-
end
|
148
|
+
end
|
149
|
+
end
|
150
|
+
end
|
151
|
+
end
|
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.7
|
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-
|
11
|
+
date: 2017-12-22 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -30,26 +30,6 @@ dependencies:
|
|
30
30
|
- - ">="
|
31
31
|
- !ruby/object:Gem::Version
|
32
32
|
version: 1.14.6
|
33
|
-
- !ruby/object:Gem::Dependency
|
34
|
-
name: closing_comments
|
35
|
-
requirement: !ruby/object:Gem::Requirement
|
36
|
-
requirements:
|
37
|
-
- - "~>"
|
38
|
-
- !ruby/object:Gem::Version
|
39
|
-
version: '0.1'
|
40
|
-
- - ">="
|
41
|
-
- !ruby/object:Gem::Version
|
42
|
-
version: 0.1.1
|
43
|
-
type: :development
|
44
|
-
prerelease: false
|
45
|
-
version_requirements: !ruby/object:Gem::Requirement
|
46
|
-
requirements:
|
47
|
-
- - "~>"
|
48
|
-
- !ruby/object:Gem::Version
|
49
|
-
version: '0.1'
|
50
|
-
- - ">="
|
51
|
-
- !ruby/object:Gem::Version
|
52
|
-
version: 0.1.1
|
53
33
|
- !ruby/object:Gem::Dependency
|
54
34
|
name: codecov
|
55
35
|
requirement: !ruby/object:Gem::Requirement
|
@@ -284,7 +264,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
284
264
|
version: '0'
|
285
265
|
requirements: []
|
286
266
|
rubyforge_project:
|
287
|
-
rubygems_version: 2.6.
|
267
|
+
rubygems_version: 2.6.13
|
288
268
|
signing_key:
|
289
269
|
specification_version: 4
|
290
270
|
summary: Immutable state with helpers to build awesome things
|