statefully 0.1.3 → 0.1.4

Sign up to get free protection for your applications and to get access to all the features.
data/spec/diff_spec.rb CHANGED
@@ -2,35 +2,43 @@ require 'spec_helper'
2
2
 
3
3
  module Statefully
4
4
  describe Diff do
5
- subject { described_class.create(current, previous) }
5
+ let(:diff) { described_class.create(current: current, previous: previous) }
6
+
7
+ context 'when created' do
8
+ let(:current) { State.create }
9
+ let(:previous) { State::None.instance }
10
+
11
+ it { expect(diff).to be_created }
12
+ end # context 'when created'
6
13
 
7
14
  context 'when key added' do
8
15
  let(:current) { State.create(key: 'val') }
9
16
  let(:previous) { State.create }
10
17
 
11
- it { expect(subject).not_to be_empty }
12
- it { expect(subject.added).to have_key(:key) }
13
- it { expect(subject.added?(:key)).to be_truthy }
14
- it { expect(subject.added.fetch(:key)).to eq 'val' }
15
- it { expect(subject.changed).to be_empty }
18
+ it { expect(diff).not_to be_empty }
19
+ it { expect(diff).not_to be_created }
20
+ it { expect(diff.added).to have_key(:key) }
21
+ it { expect(diff.added?(:key)).to be_truthy }
22
+ it { expect(diff.added.fetch(:key)).to eq 'val' }
23
+ it { expect(diff.changed).to be_empty }
16
24
 
17
- it { expect(subject.inspect).to start_with '#<Statefully::Diff::Changed' }
18
- it { expect(subject.inspect).to include 'added={key: "val"}>' }
25
+ it { expect(diff.inspect).to start_with '#<Statefully::Diff::Changed' }
26
+ it { expect(diff.inspect).to include 'added={key: "val"}>' }
19
27
  end # context 'when key added'
20
28
 
21
29
  context 'when key changed' do
22
30
  let(:current) { State.create(key: 'new') }
23
31
  let(:previous) { State.create(key: 'old') }
24
32
 
25
- it { expect(subject).not_to be_empty }
26
- it { expect(subject.added).to be_empty }
27
- it { expect(subject.changed).to have_key(:key) }
28
- it { expect(subject.changed?(:key)).to be_truthy }
33
+ it { expect(diff).not_to be_empty }
34
+ it { expect(diff.added).to be_empty }
35
+ it { expect(diff.changed).to have_key(:key) }
36
+ it { expect(diff.changed?(:key)).to be_truthy }
29
37
 
30
- it { expect(subject.inspect).to include 'changed=' }
38
+ it { expect(diff.inspect).to include 'changed=' }
31
39
 
32
40
  context 'with change' do
33
- let(:change) { subject.changed.fetch(:key) }
41
+ let(:change) { diff.changed.fetch(:key) }
34
42
 
35
43
  it { expect(change.current).to eq 'new' }
36
44
  it { expect(change.previous).to eq 'old' }
@@ -41,14 +49,14 @@ module Statefully
41
49
  let(:current) { State.create(key: 'key') }
42
50
  let(:previous) { current }
43
51
 
44
- it { expect(subject).to be_empty }
45
- it { expect(subject.inspect).to eq '#<Statefully::Diff::Unchanged>' }
52
+ it { expect(diff).to be_empty }
53
+ it { expect(diff.inspect).to eq '#<Statefully::Diff::Unchanged>' }
46
54
  end # context 'when nothing changed'
47
55
 
48
56
  shared_examples 'diff_is_empty' do
49
- it { expect(subject).to be_empty }
50
- it { expect(subject.added).to be_empty }
51
- it { expect(subject.changed).to be_empty }
57
+ it { expect(diff).to be_empty }
58
+ it { expect(diff.added).to be_empty }
59
+ it { expect(diff.changed).to be_empty }
52
60
  end # shared_examples 'diff_is_empty'
53
61
 
54
62
  context 'when failed' do
@@ -58,10 +66,10 @@ module Statefully
58
66
 
59
67
  it_behaves_like 'diff_is_empty'
60
68
 
61
- it { expect(subject.error).to eq error }
69
+ it { expect(diff.error).to eq error }
62
70
 
63
- it { expect(subject.inspect).to start_with '#<Statefully::Diff::Failed' }
64
- it { expect(subject.inspect).to include 'error=#<RuntimeError: boo!>' }
71
+ it { expect(diff.inspect).to start_with '#<Statefully::Diff::Failed' }
72
+ it { expect(diff.inspect).to include 'error=#<RuntimeError: boo!>' }
65
73
  end # context 'when failed'
66
74
 
67
75
  context 'when finished' do
@@ -70,7 +78,7 @@ module Statefully
70
78
 
71
79
  it_behaves_like 'diff_is_empty'
72
80
 
73
- it { expect(subject.inspect).to eq '#<Statefully::Diff::Finished>' }
81
+ it { expect(diff.inspect).to eq '#<Statefully::Diff::Finished>' }
74
82
  end # context 'when finished'
75
83
  end # describe Diff
76
84
  end # module Statefully
@@ -0,0 +1,13 @@
1
+ require 'spec_helper'
2
+
3
+ module Statefully
4
+ module Errors
5
+ describe StateMissing do
6
+ let(:field) { :bacon }
7
+ let(:error) { described_class.new(field) }
8
+
9
+ it { expect(error.field).to eq field }
10
+ it { expect(error.message).to eq "field 'bacon' missing from state" }
11
+ end # describe StateMissing
12
+ end # module Errors
13
+ end # module Statefully
data/spec/spec_helper.rb CHANGED
@@ -3,10 +3,12 @@ Bundler.setup
3
3
 
4
4
  require 'pry'
5
5
 
6
- require 'simplecov'
7
- SimpleCov.start
6
+ if ENV['CI'] == 'true'
7
+ require 'simplecov'
8
+ SimpleCov.start
8
9
 
9
- require 'codecov'
10
- SimpleCov.formatter = SimpleCov::Formatter::Codecov
10
+ require 'codecov'
11
+ SimpleCov.formatter = SimpleCov::Formatter::Codecov
12
+ end
11
13
 
12
14
  require 'statefully'
data/spec/state_spec.rb CHANGED
@@ -3,56 +3,87 @@ require 'spec_helper'
3
3
  module Statefully
4
4
  describe State do
5
5
  describe '.create' do
6
- subject { described_class.create(key: 'val') }
7
- it { expect(subject).to be_successful }
6
+ let(:state) { described_class.create(**args) }
7
+
8
+ context 'without keyword arguments' do
9
+ let(:args) { {} }
10
+
11
+ it { expect(state).to be_successful }
12
+
13
+ context 'with diff' do
14
+ let(:diff) { state.diff }
15
+ let(:expected) { '#<Statefully::Diff::Created>' }
16
+
17
+ it { expect(diff).to be_created }
18
+ it { expect(diff.inspect).to eq expected }
19
+ end # context 'with diff'
20
+ end # context 'without keyword arguments'
21
+
22
+ context 'with keyword arguments' do
23
+ let(:args) { { key: 'val' } }
24
+
25
+ context 'with diff' do
26
+ let(:diff) { state.diff }
27
+ let(:expected) { '#<Statefully::Diff::Created added={key: "val"}>' }
28
+
29
+ it { expect(diff).to be_created }
30
+ it { expect(diff.inspect).to eq expected }
31
+ end # context 'with diff'
32
+ end # context 'with keyword arguments'
8
33
  end # describe '.create'
9
34
  end # describe State
10
35
 
11
36
  describe 'State::Success' do
12
- let(:val) { 'val' }
13
-
14
- subject { State.create(old_key: val) }
37
+ let(:val) { 'val' }
38
+ let(:state) { State.create(old_key: val) }
15
39
 
16
40
  describe 'methods delegated to the underlying Hash' do
17
- it { expect(subject.keys).to eq [:old_key] }
18
- it { expect(subject.key?(:old_key)).to be_truthy }
19
- it { expect(subject.any? { |_, value| value == val }).to be_truthy }
41
+ it { expect(state.keys).to eq [:old_key] }
42
+ it { expect(state.key?(:old_key)).to be_truthy }
43
+ it { expect(state.any? { |_, value| value == val }).to be_truthy }
20
44
  end # describe 'methods delegated to the underlying Hash'
21
45
 
22
46
  describe "methods dynamically dispatched using 'method_missing'" do
23
- it { expect(subject.old_key).to eq val }
24
- it { expect(subject.old_key?).to be_truthy }
25
- it { expect(subject.old_key!).to eq val }
47
+ it { expect(state.old_key).to eq val }
48
+ it { expect(state.old_key?).to be_truthy }
49
+ it { expect(state.old_key!).to eq val }
26
50
 
27
- it { expect { subject.new_key }.to raise_error NoMethodError }
28
- it { expect(subject.new_key?).to be_falsey }
29
- it { expect { subject.new_key! }.to raise_error State::Missing }
51
+ it { expect { state.new_key }.to raise_error NoMethodError }
52
+ it { expect(state.new_key?).to be_falsey }
53
+ it { expect { state.new_key! }.to raise_error Errors::StateMissing }
30
54
  end # describe "methods dynamically dispatched using 'method_missing'"
31
55
 
32
56
  describe 'trivial readers' do
33
- it { expect(subject.resolve).to eq subject }
34
- it { expect(subject).to be_successful }
35
- it { expect(subject).not_to be_failed }
36
- it { expect(subject).not_to be_finished }
57
+ it { expect(state.resolve).to eq state }
58
+ it { expect(state).to be_successful }
59
+ it { expect(state).not_to be_failed }
60
+ it { expect(state).not_to be_finished }
37
61
  end # describe 'trivial readers'
38
62
 
63
+ describe 'history' do
64
+ let(:history) { state.history }
65
+
66
+ it { expect(history.length).to eq 1 }
67
+ it { expect(history.first).to be_created }
68
+ end # describe 'history'
69
+
39
70
  describe '#inspect' do
40
71
  let(:expected) { '#<Statefully::State::Success old_key="val">' }
41
72
 
42
- it { expect(subject.inspect).to eq expected }
73
+ it { expect(state.inspect).to eq expected }
43
74
  end # describe '#inspect'
44
75
 
45
76
  shared_examples 'successful_state' do
46
77
  it { expect(next_state).to be_successful }
47
78
  it { expect(next_state.old_key).to eq val }
48
79
 
49
- it { expect(next_state.previous).to eq subject }
80
+ it { expect(next_state.previous).to eq state }
50
81
  it { expect(next_state.resolve).to eq next_state }
51
82
  end # shared_examples 'successful_state'
52
83
 
53
84
  describe '#succeed' do
54
85
  let(:new_val) { 'new_val' }
55
- let(:next_state) { subject.succeed(new_key: new_val) }
86
+ let(:next_state) { state.succeed(new_key: new_val) }
56
87
 
57
88
  it_behaves_like 'successful_state'
58
89
 
@@ -64,6 +95,7 @@ module Statefully
64
95
  let(:history) { next_state.history }
65
96
 
66
97
  it { expect(history.size).to eq 2 }
98
+ it { expect(history.first).not_to be_created }
67
99
  it { expect(history.first.added).to include :new_key }
68
100
  it { expect(history.last.added).to include :old_key }
69
101
  end # context 'with history'
@@ -71,21 +103,16 @@ module Statefully
71
103
 
72
104
  describe '#fail' do
73
105
  let(:error) { RuntimeError.new('boo!') }
74
- let(:next_state) { subject.fail(error) }
106
+ let(:next_state) { state.fail(error) }
75
107
 
76
108
  it { expect(next_state).not_to be_successful }
77
109
  it { expect(next_state).to be_failed }
78
110
  it { expect(next_state).not_to be_finished }
79
- it { expect(subject).not_to be_finished }
111
+ it { expect(state).not_to be_finished }
80
112
  it { expect(next_state.old_key).to eq val }
81
- it { expect(next_state.previous).to eq subject }
113
+ it { expect(next_state.previous).to eq state }
82
114
  it { expect(next_state.error).to eq error }
83
-
84
- it 'raises passed error on #resolve' do
85
- expect { next_state.resolve }.to raise_error do |err|
86
- expect(err).to eq error
87
- end
88
- end
115
+ it { expect { next_state.resolve }.to raise_error(error) }
89
116
 
90
117
  describe '#inspect' do
91
118
  let(:inspect) { next_state.inspect }
@@ -106,7 +133,7 @@ module Statefully
106
133
 
107
134
  describe '#finish' do
108
135
  let(:new_val) { 'new_val' }
109
- let(:next_state) { subject.finish }
136
+ let(:next_state) { state.finish }
110
137
 
111
138
  it_behaves_like 'successful_state'
112
139
 
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.3
4
+ version: 0.1.4
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-21 00:00:00.000000000 Z
11
+ date: 2017-05-24 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -30,6 +30,80 @@ 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
+ - !ruby/object:Gem::Dependency
54
+ name: codecov
55
+ requirement: !ruby/object:Gem::Requirement
56
+ requirements:
57
+ - - "~>"
58
+ - !ruby/object:Gem::Version
59
+ version: '0.1'
60
+ - - ">="
61
+ - !ruby/object:Gem::Version
62
+ version: 0.1.10
63
+ type: :development
64
+ prerelease: false
65
+ version_requirements: !ruby/object:Gem::Requirement
66
+ requirements:
67
+ - - "~>"
68
+ - !ruby/object:Gem::Version
69
+ version: '0.1'
70
+ - - ">="
71
+ - !ruby/object:Gem::Version
72
+ version: 0.1.10
73
+ - !ruby/object:Gem::Dependency
74
+ name: ensure_version_bump
75
+ requirement: !ruby/object:Gem::Requirement
76
+ requirements:
77
+ - - "~>"
78
+ - !ruby/object:Gem::Version
79
+ version: '0.1'
80
+ type: :development
81
+ prerelease: false
82
+ version_requirements: !ruby/object:Gem::Requirement
83
+ requirements:
84
+ - - "~>"
85
+ - !ruby/object:Gem::Version
86
+ version: '0.1'
87
+ - !ruby/object:Gem::Dependency
88
+ name: pry
89
+ requirement: !ruby/object:Gem::Requirement
90
+ requirements:
91
+ - - "~>"
92
+ - !ruby/object:Gem::Version
93
+ version: '0.10'
94
+ - - ">="
95
+ - !ruby/object:Gem::Version
96
+ version: 0.10.4
97
+ type: :development
98
+ prerelease: false
99
+ version_requirements: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - "~>"
102
+ - !ruby/object:Gem::Version
103
+ version: '0.10'
104
+ - - ">="
105
+ - !ruby/object:Gem::Version
106
+ version: 0.10.4
33
107
  - !ruby/object:Gem::Dependency
34
108
  name: rake
35
109
  requirement: !ruby/object:Gem::Requirement
@@ -44,6 +118,128 @@ dependencies:
44
118
  - - "~>"
45
119
  - !ruby/object:Gem::Version
46
120
  version: '12.0'
121
+ - !ruby/object:Gem::Dependency
122
+ name: reek
123
+ requirement: !ruby/object:Gem::Requirement
124
+ requirements:
125
+ - - "~>"
126
+ - !ruby/object:Gem::Version
127
+ version: '4.6'
128
+ - - ">="
129
+ - !ruby/object:Gem::Version
130
+ version: 4.6.2
131
+ type: :development
132
+ prerelease: false
133
+ version_requirements: !ruby/object:Gem::Requirement
134
+ requirements:
135
+ - - "~>"
136
+ - !ruby/object:Gem::Version
137
+ version: '4.6'
138
+ - - ">="
139
+ - !ruby/object:Gem::Version
140
+ version: 4.6.2
141
+ - !ruby/object:Gem::Dependency
142
+ name: rspec
143
+ requirement: !ruby/object:Gem::Requirement
144
+ requirements:
145
+ - - "~>"
146
+ - !ruby/object:Gem::Version
147
+ version: '3.6'
148
+ type: :development
149
+ prerelease: false
150
+ version_requirements: !ruby/object:Gem::Requirement
151
+ requirements:
152
+ - - "~>"
153
+ - !ruby/object:Gem::Version
154
+ version: '3.6'
155
+ - !ruby/object:Gem::Dependency
156
+ name: rubocop
157
+ requirement: !ruby/object:Gem::Requirement
158
+ requirements:
159
+ - - "~>"
160
+ - !ruby/object:Gem::Version
161
+ version: '0.49'
162
+ type: :development
163
+ prerelease: false
164
+ version_requirements: !ruby/object:Gem::Requirement
165
+ requirements:
166
+ - - "~>"
167
+ - !ruby/object:Gem::Version
168
+ version: '0.49'
169
+ - !ruby/object:Gem::Dependency
170
+ name: rubocop-rspec
171
+ requirement: !ruby/object:Gem::Requirement
172
+ requirements:
173
+ - - "~>"
174
+ - !ruby/object:Gem::Version
175
+ version: '1.15'
176
+ - - ">="
177
+ - !ruby/object:Gem::Version
178
+ version: 1.15.1
179
+ type: :development
180
+ prerelease: false
181
+ version_requirements: !ruby/object:Gem::Requirement
182
+ requirements:
183
+ - - "~>"
184
+ - !ruby/object:Gem::Version
185
+ version: '1.15'
186
+ - - ">="
187
+ - !ruby/object:Gem::Version
188
+ version: 1.15.1
189
+ - !ruby/object:Gem::Dependency
190
+ name: simplecov
191
+ requirement: !ruby/object:Gem::Requirement
192
+ requirements:
193
+ - - "~>"
194
+ - !ruby/object:Gem::Version
195
+ version: '0.14'
196
+ - - ">="
197
+ - !ruby/object:Gem::Version
198
+ version: 0.14.1
199
+ type: :development
200
+ prerelease: false
201
+ version_requirements: !ruby/object:Gem::Requirement
202
+ requirements:
203
+ - - "~>"
204
+ - !ruby/object:Gem::Version
205
+ version: '0.14'
206
+ - - ">="
207
+ - !ruby/object:Gem::Version
208
+ version: 0.14.1
209
+ - !ruby/object:Gem::Dependency
210
+ name: yard
211
+ requirement: !ruby/object:Gem::Requirement
212
+ requirements:
213
+ - - "~>"
214
+ - !ruby/object:Gem::Version
215
+ version: '0.9'
216
+ - - ">="
217
+ - !ruby/object:Gem::Version
218
+ version: 0.9.9
219
+ type: :development
220
+ prerelease: false
221
+ version_requirements: !ruby/object:Gem::Requirement
222
+ requirements:
223
+ - - "~>"
224
+ - !ruby/object:Gem::Version
225
+ version: '0.9'
226
+ - - ">="
227
+ - !ruby/object:Gem::Version
228
+ version: 0.9.9
229
+ - !ruby/object:Gem::Dependency
230
+ name: yardstick
231
+ requirement: !ruby/object:Gem::Requirement
232
+ requirements:
233
+ - - ">="
234
+ - !ruby/object:Gem::Version
235
+ version: '0'
236
+ type: :development
237
+ prerelease: false
238
+ version_requirements: !ruby/object:Gem::Requirement
239
+ requirements:
240
+ - - ">="
241
+ - !ruby/object:Gem::Version
242
+ version: '0'
47
243
  description: Immutable state with helpers to build awesome things
48
244
  email:
49
245
  executables: []
@@ -51,16 +247,20 @@ extensions: []
51
247
  extra_rdoc_files: []
52
248
  files:
53
249
  - lib/statefully.rb
250
+ - lib/statefully/change.rb
54
251
  - lib/statefully/diff.rb
252
+ - lib/statefully/errors.rb
55
253
  - lib/statefully/inspect.rb
56
254
  - lib/statefully/state.rb
57
255
  - spec/diff_spec.rb
256
+ - spec/errors_spec.rb
58
257
  - spec/spec_helper.rb
59
258
  - spec/state_spec.rb
60
259
  homepage: https://github.com/marcinwyszynski/statefully
61
260
  licenses:
62
261
  - MIT
63
- metadata: {}
262
+ metadata:
263
+ yard.run: yard
64
264
  post_install_message:
65
265
  rdoc_options: []
66
266
  require_paths:
@@ -83,5 +283,6 @@ specification_version: 4
83
283
  summary: Immutable state with helpers to build awesome things
84
284
  test_files:
85
285
  - spec/diff_spec.rb
286
+ - spec/errors_spec.rb
86
287
  - spec/spec_helper.rb
87
288
  - spec/state_spec.rb