statefully 0.1.6 → 0.1.7
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/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
|