much-result 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,57 @@
1
+ require "much-result"
2
+
3
+ class MuchResult; end
4
+ class MuchResult::Aggregate
5
+ def self.call(values)
6
+ new(values).call
7
+ end
8
+
9
+ def initialize(values)
10
+ @values = values
11
+ end
12
+
13
+ def call
14
+ combine_values(@values)
15
+ end
16
+
17
+ private
18
+
19
+ def combine_values(values)
20
+ combine_in_a_collection(array_wrap(values))
21
+ end
22
+
23
+ def combine_in_a_collection(values)
24
+ if all_hash_values?(values)
25
+ values.
26
+ reduce { |acc, value| combine_in_a_hash(acc, value) }.
27
+ transform_values { |nested_values| combine_values(nested_values) }
28
+ else
29
+ array_wrap(
30
+ values.reduce([]) { |acc, value| combine_in_an_array(acc, value) }
31
+ )
32
+ end
33
+ end
34
+
35
+ def combine_in_a_hash(hash1, hash2)
36
+ ((h1 = hash1 || {}).keys + (h2 = hash2 || {}).keys).
37
+ uniq.
38
+ reduce({}) { |hash, key|
39
+ hash[key] = combine_in_an_array(h1[key], h2[key])
40
+ hash
41
+ }
42
+ end
43
+
44
+ def combine_in_an_array(acc, other)
45
+ array_wrap(acc) + array_wrap(other)
46
+ end
47
+
48
+ def array_wrap(value)
49
+ value.kind_of?(Array) ? value : [value]
50
+ end
51
+
52
+ def all_hash_values?(values)
53
+ (compacted = values.compact).reduce(compacted.any?) { |acc, value|
54
+ acc && value.kind_of?(::Hash)
55
+ }
56
+ end
57
+ end
@@ -0,0 +1,56 @@
1
+ require "much-result"
2
+
3
+ class MuchResult; end
4
+ class MuchResult::Transaction
5
+ def self.halt_throw_value
6
+ :muchresult_transaction_halt
7
+ end
8
+
9
+ def self.call(receiver, **result_kargs, &block)
10
+ new(receiver, **result_kargs).call(&block)
11
+ end
12
+
13
+ def initialize(receiver, **result_kargs)
14
+ @receiver = receiver
15
+ @result_kargs = result_kargs
16
+
17
+ result.much_result_transaction_rolled_back = false
18
+ result.much_result_transaction_halted = false
19
+ end
20
+
21
+ def result
22
+ @result ||= MuchResult.success(**@result_kargs)
23
+ end
24
+
25
+ def call(&block)
26
+ begin
27
+ @receiver.transaction do
28
+ catch(self.class.halt_throw_value) { block.call(self) }
29
+ end
30
+ rescue MuchResult::Rollback
31
+ # do nothing
32
+ end
33
+
34
+ result
35
+ end
36
+
37
+ def rollback
38
+ result.much_result_transaction_rolled_back = true
39
+ raise MuchResult::Rollback
40
+ end
41
+
42
+ def halt
43
+ result.much_result_transaction_halted = true
44
+ throw(self.class.halt_throw_value)
45
+ end
46
+
47
+ private
48
+
49
+ def respond_to_missing?(*args)
50
+ result.send(:respond_to_missing?, *args)
51
+ end
52
+
53
+ def method_missing(method, *args, &block)
54
+ result.public_send(method, *args, &block)
55
+ end
56
+ end
@@ -0,0 +1,3 @@
1
+ class MuchResult
2
+ VERSION = "0.1.0"
3
+ end
File without changes
@@ -0,0 +1,24 @@
1
+ # -*- encoding: utf-8 -*-
2
+ lib = File.expand_path("../lib", __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require "much-result/version"
5
+
6
+ Gem::Specification.new do |gem|
7
+ gem.name = "much-result"
8
+ gem.version = MuchResult::VERSION
9
+ gem.authors = ["Kelly Redding", "Collin Redding"]
10
+ gem.email = ["kelly@kellyredding.com", "collin.redding@me.com"]
11
+ gem.summary = "API for managing the results of operations."
12
+ gem.description = "API for managing the results of operations."
13
+ gem.homepage = "https://github.com/redding/much-result"
14
+ gem.license = "MIT"
15
+
16
+ gem.files = `git ls-files | grep "^[^.]"`.split($/)
17
+ gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
18
+ gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
19
+ gem.require_paths = ["lib"]
20
+
21
+ gem.required_ruby_version = "~> 2.5"
22
+
23
+ gem.add_development_dependency("assert", ["~> 2.18.4"])
24
+ end
@@ -0,0 +1,10 @@
1
+ # this file is automatically required when you run `assert`
2
+ # put any test helpers here
3
+
4
+ # add the root dir to the load path
5
+ $LOAD_PATH.unshift(File.expand_path("../..", __FILE__))
6
+
7
+ # require pry for debugging (`binding.pry`)
8
+ require "pry"
9
+
10
+ require "test/support/factory"
@@ -0,0 +1,42 @@
1
+ require "assert/factory"
2
+ require "much-stub/call"
3
+
4
+ module Factory
5
+ extend Assert::Factory
6
+
7
+ def self.value
8
+ [Factory.integer, Factory.string, Object.new].sample
9
+ end
10
+
11
+ def self.hash_value(with_nested_hash = true)
12
+ {
13
+ value1: Factory.value,
14
+ value2: with_nested_hash ? Factory.hash_value(false) : Factory.value
15
+ }
16
+ end
17
+
18
+ def self.backtrace
19
+ Factory.integer(3).times.map{ Factory.path }
20
+ end
21
+
22
+ def self.transaction_receiver
23
+ FakeTransactionReceiver.new
24
+ end
25
+
26
+ class FakeTransactionReceiver
27
+ attr_reader :last_transaction_call
28
+
29
+ def transaction(&block)
30
+ @rolled_back = false
31
+ @last_transaction_call = MuchStub::Call.new(&block)
32
+ block.call
33
+ rescue => exception
34
+ @rolled_back = true
35
+ raise exception
36
+ end
37
+
38
+ def rolled_back?
39
+ !!@rolled_back
40
+ end
41
+ end
42
+ end
File without changes
@@ -0,0 +1,103 @@
1
+ require "assert"
2
+ require "much-result/aggregate"
3
+
4
+ class MuchResult::Aggregate
5
+ class UnitTests < Assert::Context
6
+ desc "MuchResult::Aggregate"
7
+ subject { unit_class }
8
+
9
+ let(:unit_class) { MuchResult::Aggregate }
10
+
11
+ let(:values1) {
12
+ [Factory.value, Factory.value, Factory.value, Hash.new]
13
+ }
14
+ let(:hash_values1) {
15
+ [Factory.hash_value, Factory.hash_value, Factory.hash_value]
16
+ }
17
+
18
+ should have_imeths :call
19
+
20
+ should "build instances and call them" do
21
+ Assert.stub_tap_on_call(subject, :new) { |instance, call|
22
+ @instance_new_call = call
23
+ Assert.stub(instance, :call) { @instance_called = true }
24
+ }
25
+
26
+ subject.call(values1)
27
+
28
+ assert_that(@instance_new_call.args).equals([values1])
29
+ assert_that(@instance_called).is_true
30
+ end
31
+ end
32
+
33
+ class InitTests < UnitTests
34
+ desc "when init"
35
+ subject { unit_class.new(init_values) }
36
+
37
+ let(:init_values) { [values1, hash_values1, [], nil].sample }
38
+
39
+ should have_imeths :call
40
+ end
41
+
42
+ class CalledWithAnEmptyArrayTests < InitTests
43
+ desc "and called with an empty Array"
44
+
45
+ let(:init_values) { [] }
46
+ # let(:init_values) { [[], nil, [nil, nil]].sample }
47
+
48
+ should "return an empty Array" do
49
+ assert_that(subject.call).equals([])
50
+ end
51
+ end
52
+
53
+ class CalledWithASingleNonHashValueTests < InitTests
54
+ desc "and called with single non-Hash value"
55
+
56
+ let(:init_values) { [Factory.value, nil].sample }
57
+
58
+ should "return the value wrapped in an Array" do
59
+ assert_that(subject.call).equals([init_values])
60
+ end
61
+ end
62
+
63
+ class CalledWithASingleHashValueTests < InitTests
64
+ desc "and called with single Hash value"
65
+
66
+ let(:value1) { [Factory.value, nil].sample }
67
+ let(:init_values) { { value: value1 } }
68
+
69
+ should "return the Hash with its values wrapped in an Array" do
70
+ assert_that(subject.call).equals(value: [value1])
71
+ end
72
+ end
73
+
74
+ class CalledWithAMixedValueArrayTests < InitTests
75
+ desc "and called with a mixed-value Array"
76
+
77
+ let(:init_values) { [nil, values1, [], { value: 1 }, nil] }
78
+
79
+ should "combines the values into an Array, flattening any sub-Arrays" do
80
+ assert_that(subject.call).equals([nil, *values1, { value: 1 }, nil])
81
+ end
82
+ end
83
+
84
+ class CalledWithAnAllHashValueArrayTests < InitTests
85
+ desc "and called with an all-Hash-value Array"
86
+
87
+ let(:init_values) { [nil] + hash_values1 + [nil] }
88
+
89
+ let(:expected_aggregate_value) {
90
+ {
91
+ value1: init_values.map { |hash| (hash || {})[:value1] },
92
+ value2: {
93
+ value1: init_values.map { |hash| (hash || {}).dig(:value2, :value1) },
94
+ value2: init_values.map { |hash| (hash || {}).dig(:value2, :value2) }
95
+ }
96
+ }
97
+ }
98
+
99
+ should "recursively combine the hash values, removing any nils" do
100
+ assert_that(subject.call).equals(expected_aggregate_value)
101
+ end
102
+ end
103
+ end
@@ -0,0 +1,447 @@
1
+ require "assert"
2
+ require "much-result"
3
+
4
+ class MuchResult
5
+ class UnitTests < Assert::Context
6
+ desc "MuchResult"
7
+ subject { unit_class }
8
+
9
+ let(:unit_class) { MuchResult }
10
+
11
+ let(:identifier1) { Factory.string }
12
+ let(:description1) { Factory.string }
13
+ let(:backtrace1) { Factory.backtrace }
14
+ let(:value1) { Factory.value }
15
+
16
+ should have_imeths :success, :failure, :for, :tap, :transaction
17
+
18
+ should "build success instances" do
19
+ result = subject.success
20
+
21
+ assert_that(result.success?).is_true
22
+ assert_that(result.failure?).is_false
23
+
24
+ assert_that(result.sub_results).equals([])
25
+ assert_that(result.success_sub_results).equals([])
26
+ assert_that(result.failure_sub_results).equals([])
27
+
28
+ assert_that(result.all_results).equals([result])
29
+ assert_that(result.all_success_results).equals([result])
30
+ assert_that(result.all_failure_results).equals([])
31
+ end
32
+
33
+ should "build failure instances" do
34
+ result = subject.failure
35
+
36
+ assert_that(result.success?).is_false
37
+ assert_that(result.failure?).is_true
38
+
39
+ assert_that(result.sub_results).equals([])
40
+ assert_that(result.success_sub_results).equals([])
41
+ assert_that(result.failure_sub_results).equals([])
42
+
43
+ assert_that(result.all_results).equals([result])
44
+ assert_that(result.all_success_results).equals([])
45
+ assert_that(result.all_failure_results).equals([result])
46
+ end
47
+
48
+ should "build instances based on given values" do
49
+ true_result = subject.for(true, value: value1)
50
+ assert_that(true_result.success?).is_true
51
+ assert_that(true_result.failure?).is_false
52
+ assert_that(true_result.value).equals(value1)
53
+
54
+ false_result = subject.for(false, value: value1)
55
+ assert_that(false_result.success?).is_false
56
+ assert_that(false_result.failure?).is_true
57
+ assert_that(false_result.value).equals(value1)
58
+
59
+ value1_result = subject.for(value1, value: value1)
60
+ assert_that(value1_result.success?).is_true
61
+ assert_that(value1_result.failure?).is_false
62
+ assert_that(value1_result.value).equals(value1)
63
+
64
+ nil_result = subject.for(nil, value: value1)
65
+ assert_that(nil_result.success?).is_false
66
+ assert_that(nil_result.failure?).is_true
67
+ assert_that(nil_result.value).equals(value1)
68
+
69
+ result_result = subject.for(true_result, value2: value1)
70
+ assert_that(result_result).is_the_same_as(true_result)
71
+ assert_that(result_result.value2).equals(value1)
72
+ end
73
+
74
+ should "build instances yielded to a given block" do
75
+ yielded_result = nil
76
+ tap_result =
77
+ subject.tap { |result|
78
+ yielded_result = result
79
+
80
+ assert_that(result.success?).is_true
81
+ assert_that(result.sub_results.size).equals(0)
82
+ assert_that(result.all_results.size).equals(1)
83
+ }
84
+ assert_that(tap_result).is_the_same_as(yielded_result)
85
+ end
86
+
87
+ should "call transactions on a transaction receiver" do
88
+ MuchStub.on_call(MuchResult::Transaction, :call) { |call|
89
+ @transaction_call = call
90
+ }
91
+
92
+ receiver1 = Factory.transaction_receiver
93
+ kargs1 = {
94
+ backtrace: Factory.backtrace,
95
+ value: value1
96
+ }
97
+ block1 = -> {}
98
+ subject.transaction(receiver1, **kargs1, &block1)
99
+
100
+ assert_that(@transaction_call.pargs).equals([receiver1])
101
+ assert_that(@transaction_call.kargs).equals(kargs1)
102
+ assert_that(@transaction_call.block).equals(block1)
103
+ end
104
+
105
+ should "halt transactions" do
106
+ receiver1 = Factory.transaction_receiver
107
+ result =
108
+ subject.transaction(receiver1) do |transaction|
109
+ transaction.capture { "something1"}
110
+ transaction.halt
111
+ transaction.capture { "something2" }
112
+ end
113
+
114
+ assert_that(result.sub_results.size).equals(1)
115
+ end
116
+ end
117
+
118
+ class InitTests < UnitTests
119
+ desc "when init"
120
+ subject { unit_class.success }
121
+
122
+ let(:failure1) {
123
+ unit_class.failure(description: Factory.string)
124
+ }
125
+ let(:failure2) {
126
+ unit_class.failure(exception: StandardError.new(Factory.string))
127
+ }
128
+
129
+ should have_imeths :description, :backtrace, :set
130
+ should have_imeths :success?, :failure?
131
+ should have_imeths :capture_for, :capture_for!
132
+ should have_imeths :capture_for_all, :capture_for_all!
133
+ should have_imeths :capture, :capture!
134
+ should have_imeths :capture_all, :capture_all!
135
+ should have_imeths :capture_exception
136
+ should have_imeths :sub_results, :success_sub_results, :failure_sub_results
137
+ should have_imeths :all_results, :all_success_results, :all_failure_results
138
+ should have_imeths :get_for_sub_results
139
+ should have_imeths :get_for_success_sub_results, :get_for_failure_sub_results
140
+ should have_imeths :get_for_all_results
141
+ should have_imeths :get_for_all_success_results, :get_for_all_failure_results
142
+ should have_imeths :to_much_result
143
+
144
+ should "know its attributes" do
145
+ assert_that(subject.description).is_nil
146
+ assert_that(subject.backtrace).is_not_nil
147
+ assert_that(subject.backtrace).is_not_empty
148
+
149
+ result =
150
+ unit_class.success(
151
+ identifier: identifier1,
152
+ description: description1,
153
+ backtrace: backtrace1,
154
+ value: value1
155
+ )
156
+ assert_that(result.identifier).equals(identifier1)
157
+ assert_that(result.description).equals(description1)
158
+ assert_that(result.backtrace).equals(backtrace1)
159
+ assert_that(result.value).equals(value1)
160
+
161
+ exception = result.capture_exception
162
+ assert_that(exception).is_instance_of(MuchResult::Error)
163
+ assert_that(exception.message).equals(description1)
164
+ assert_that(exception.backtrace).equals(backtrace1)
165
+ end
166
+
167
+ should "allow setting arbitrary values" do
168
+ assert_that(subject.other_value).is_nil
169
+
170
+ subject.set(other_value: value1)
171
+ assert_that(subject.other_value).equals(value1)
172
+ end
173
+
174
+ should "capture MuchResults as sub-results" do
175
+ subject.capture_for(unit_class.success(values: { value1: Factory.value }))
176
+ assert_that(subject.success?).is_true
177
+ assert_that(subject.sub_results.size).equals(1)
178
+ assert_that(subject.success_sub_results.size).equals(1)
179
+ assert_that(subject.failure_sub_results.size).equals(0)
180
+ assert_that(subject.get_for_sub_results("values")[:value1]).equals(
181
+ [
182
+ subject.success_sub_results.first.values[:value1]
183
+ ])
184
+ assert_that(subject.get_for_success_sub_results("values")[:value1]).equals(
185
+ [
186
+ subject.success_sub_results.first.values[:value1]
187
+ ])
188
+ assert_that(subject.get_for_failure_sub_results("values")).equals(
189
+ [])
190
+ assert_that(subject.all_results.size).equals(2)
191
+ assert_that(subject.all_success_results.size).equals(2)
192
+ assert_that(subject.all_failure_results.size).equals(0)
193
+ assert_that(subject.get_for_all_results("values")[:value1]).equals(
194
+ [
195
+ nil,
196
+ subject.success_sub_results.first.values[:value1]
197
+ ])
198
+ assert_that(subject.get_for_all_success_results("values")[:value1]).equals(
199
+ [
200
+ nil,
201
+ subject.success_sub_results.first.values[:value1]
202
+ ])
203
+ assert_that(subject.get_for_all_failure_results("values")).equals(
204
+ [])
205
+
206
+ subject.capture_for(unit_class.failure(values: { value1: Factory.value }))
207
+ assert_that(subject.success?).is_false
208
+ assert_that(subject.sub_results.size).equals(2)
209
+ assert_that(subject.success_sub_results.size).equals(1)
210
+ assert_that(subject.failure_sub_results.size).equals(1)
211
+ assert_that(subject.get_for_sub_results("values")[:value1]).equals(
212
+ [
213
+ subject.success_sub_results.first.values[:value1],
214
+ subject.failure_sub_results.first.values[:value1]
215
+ ])
216
+ assert_that(subject.get_for_success_sub_results("values")[:value1]).equals(
217
+ [
218
+ subject.success_sub_results.first.values[:value1]
219
+ ])
220
+ assert_that(subject.get_for_failure_sub_results("values")[:value1]).equals(
221
+ [
222
+ subject.failure_sub_results.first.values[:value1]
223
+ ])
224
+ assert_that(subject.all_results.size).equals(3)
225
+ assert_that(subject.all_success_results.size).equals(1)
226
+ assert_that(subject.all_failure_results.size).equals(2)
227
+ assert_that(subject.get_for_all_results("values")[:value1]).equals(
228
+ [
229
+ nil,
230
+ subject.success_sub_results.first.values[:value1],
231
+ subject.failure_sub_results.first.values[:value1]
232
+ ])
233
+ assert_that(subject.get_for_all_success_results("values")[:value1]).equals(
234
+ [
235
+ subject.success_sub_results.first.values[:value1]
236
+ ])
237
+ assert_that(subject.get_for_all_failure_results("values")[:value1]).equals(
238
+ [
239
+ nil,
240
+ subject.failure_sub_results.first.values[:value1]
241
+ ])
242
+
243
+ result = unit_class.success
244
+
245
+ result.capture_for([true, Factory.integer, Factory.string].sample)
246
+ assert_that(result.success?).is_true
247
+ assert_that(result.sub_results.size).equals(1)
248
+ assert_that(result.success_sub_results.size).equals(1)
249
+ assert_that(result.failure_sub_results.size).equals(0)
250
+ assert_that(result.all_results.size).equals(2)
251
+ assert_that(result.all_success_results.size).equals(2)
252
+ assert_that(result.all_failure_results.size).equals(0)
253
+
254
+ result.capture_for([false, nil].sample)
255
+ assert_that(result.success?).is_false
256
+ assert_that(result.sub_results.size).equals(2)
257
+ assert_that(result.success_sub_results.size).equals(1)
258
+ assert_that(result.failure_sub_results.size).equals(1)
259
+ assert_that(result.all_results.size).equals(3)
260
+ assert_that(result.all_success_results.size).equals(1)
261
+ assert_that(result.all_failure_results.size).equals(2)
262
+
263
+ result = unit_class.success
264
+
265
+ # Test the default built capture exception.
266
+ exception =
267
+ assert_that(-> {
268
+ result.capture_for!(failure1)
269
+ }).raises(MuchResult::Error)
270
+ assert_that(exception.message).equals(failure1.description)
271
+ assert_that(exception.backtrace).equals(failure1.backtrace)
272
+ assert_that(result.success?).is_false
273
+ assert_that(result.sub_results.size).equals(1)
274
+ assert_that(result.success_sub_results.size).equals(0)
275
+ assert_that(result.failure_sub_results.size).equals(1)
276
+ assert_that(result.all_results.size).equals(2)
277
+ assert_that(result.all_success_results.size).equals(0)
278
+ assert_that(result.all_failure_results.size).equals(2)
279
+
280
+ # Test that we prefer any set `result.exception` over the default built
281
+ # capture exception.
282
+ exception =
283
+ assert_that(-> {
284
+ result.capture_for!(failure2)
285
+ }).raises(failure2.exception.class)
286
+ assert_that(exception.message).equals(failure2.exception.message)
287
+ assert_that(exception.backtrace).equals(failure2.exception.backtrace)
288
+ assert_that(result.success?).is_false
289
+ assert_that(result.sub_results.size).equals(2)
290
+ assert_that(result.success_sub_results.size).equals(0)
291
+ assert_that(result.failure_sub_results.size).equals(2)
292
+ assert_that(result.all_results.size).equals(3)
293
+ assert_that(result.all_success_results.size).equals(0)
294
+ assert_that(result.all_failure_results.size).equals(3)
295
+ end
296
+
297
+ should "capture MuchResults from an Array as sub-results" do
298
+ subject.capture_for_all([unit_class.success, unit_class.failure])
299
+ assert_that(subject.success?).is_false
300
+ assert_that(subject.sub_results.size).equals(2)
301
+ assert_that(subject.success_sub_results.size).equals(1)
302
+ assert_that(subject.failure_sub_results.size).equals(1)
303
+ assert_that(subject.all_results.size).equals(3)
304
+ assert_that(subject.all_success_results.size).equals(1)
305
+ assert_that(subject.all_failure_results.size).equals(2)
306
+
307
+ result = unit_class.success
308
+
309
+ result.capture_for_all(
310
+ [
311
+ [true, Factory.integer, Factory.string].sample,
312
+ [false, nil].sample
313
+ ]
314
+ )
315
+ assert_that(result.success?).is_false
316
+ assert_that(result.sub_results.size).equals(2)
317
+ assert_that(result.success_sub_results.size).equals(1)
318
+ assert_that(result.failure_sub_results.size).equals(1)
319
+ assert_that(result.all_results.size).equals(3)
320
+ assert_that(result.all_success_results.size).equals(1)
321
+ assert_that(result.all_failure_results.size).equals(2)
322
+
323
+ result = unit_class.success
324
+
325
+ exception =
326
+ assert_that(-> {
327
+ result.capture_for_all!([failure1, failure2])
328
+ }).raises(MuchResult::Error)
329
+ assert_that(exception.message).equals(failure1.description)
330
+ assert_that(exception.backtrace).equals(failure1.backtrace)
331
+ assert_that(result.success?).is_false
332
+ assert_that(result.sub_results.size).equals(2)
333
+ assert_that(result.success_sub_results.size).equals(0)
334
+ assert_that(result.failure_sub_results.size).equals(2)
335
+ assert_that(result.all_results.size).equals(3)
336
+ assert_that(result.all_success_results.size).equals(0)
337
+ assert_that(result.all_failure_results.size).equals(3)
338
+ end
339
+
340
+ should "capture MuchResults from a block as sub-results" do
341
+ subject.capture { unit_class.success }
342
+ assert_that(subject.success?).is_true
343
+ assert_that(subject.sub_results.size).equals(1)
344
+ assert_that(subject.success_sub_results.size).equals(1)
345
+ assert_that(subject.failure_sub_results.size).equals(0)
346
+ assert_that(subject.all_results.size).equals(2)
347
+ assert_that(subject.all_success_results.size).equals(2)
348
+ assert_that(subject.all_failure_results.size).equals(0)
349
+
350
+ subject.capture { unit_class.failure }
351
+ assert_that(subject.success?).is_false
352
+ assert_that(subject.sub_results.size).equals(2)
353
+ assert_that(subject.success_sub_results.size).equals(1)
354
+ assert_that(subject.failure_sub_results.size).equals(1)
355
+ assert_that(subject.all_results.size).equals(3)
356
+ assert_that(subject.all_success_results.size).equals(1)
357
+ assert_that(subject.all_failure_results.size).equals(2)
358
+
359
+ result = unit_class.success
360
+
361
+ result.capture { [true, Factory.integer, Factory.string].sample }
362
+ assert_that(result.success?).is_true
363
+ assert_that(result.sub_results.size).equals(1)
364
+ assert_that(result.success_sub_results.size).equals(1)
365
+ assert_that(result.failure_sub_results.size).equals(0)
366
+ assert_that(result.all_results.size).equals(2)
367
+ assert_that(result.all_success_results.size).equals(2)
368
+ assert_that(result.all_failure_results.size).equals(0)
369
+
370
+ result.capture { [false, nil].sample }
371
+ assert_that(result.success?).is_false
372
+ assert_that(result.sub_results.size).equals(2)
373
+ assert_that(result.success_sub_results.size).equals(1)
374
+ assert_that(result.failure_sub_results.size).equals(1)
375
+ assert_that(result.all_results.size).equals(3)
376
+ assert_that(result.all_success_results.size).equals(1)
377
+ assert_that(result.all_failure_results.size).equals(2)
378
+
379
+ result = unit_class.success
380
+
381
+ exception =
382
+ assert_that(-> {
383
+ result.capture! { failure1 }
384
+ }).raises(MuchResult::Error)
385
+ assert_that(exception.message).equals(failure1.description)
386
+ assert_that(exception.backtrace).equals(failure1.backtrace)
387
+ assert_that(result.success?).is_false
388
+ assert_that(result.sub_results.size).equals(1)
389
+ assert_that(result.success_sub_results.size).equals(0)
390
+ assert_that(result.failure_sub_results.size).equals(1)
391
+ assert_that(result.all_results.size).equals(2)
392
+ assert_that(result.all_success_results.size).equals(0)
393
+ assert_that(result.all_failure_results.size).equals(2)
394
+ end
395
+
396
+ should "capture MuchResults from a block from an Array as sub-results" do
397
+ subject.capture_all { [unit_class.success, unit_class.failure] }
398
+ assert_that(subject.success?).is_false
399
+ assert_that(subject.sub_results.size).equals(2)
400
+ assert_that(subject.success_sub_results.size).equals(1)
401
+ assert_that(subject.failure_sub_results.size).equals(1)
402
+ assert_that(subject.all_results.size).equals(3)
403
+ assert_that(subject.all_success_results.size).equals(1)
404
+ assert_that(subject.all_failure_results.size).equals(2)
405
+
406
+ result = unit_class.success
407
+
408
+ result.capture_all do
409
+ [
410
+ [true, Factory.integer, Factory.string].sample,
411
+ [false, nil].sample
412
+ ]
413
+ end
414
+ assert_that(result.success?).is_false
415
+ assert_that(result.sub_results.size).equals(2)
416
+ assert_that(result.success_sub_results.size).equals(1)
417
+ assert_that(result.failure_sub_results.size).equals(1)
418
+ assert_that(result.all_results.size).equals(3)
419
+ assert_that(result.all_success_results.size).equals(1)
420
+ assert_that(result.all_failure_results.size).equals(2)
421
+
422
+ result = unit_class.success
423
+
424
+ exception =
425
+ assert_that(-> {
426
+ result.capture_all! { [failure1, failure2] }
427
+ }).raises(MuchResult::Error)
428
+ assert_that(exception.message).equals(failure1.description)
429
+ assert_that(exception.backtrace).equals(failure1.backtrace)
430
+ assert_that(result.success?).is_false
431
+ assert_that(result.sub_results.size).equals(2)
432
+ assert_that(result.success_sub_results.size).equals(0)
433
+ assert_that(result.failure_sub_results.size).equals(2)
434
+ assert_that(result.all_results.size).equals(3)
435
+ assert_that(result.all_success_results.size).equals(0)
436
+ assert_that(result.all_failure_results.size).equals(3)
437
+ end
438
+
439
+ should "convert itself to a MuchResult" do
440
+ assert_that(subject.value).is_nil
441
+
442
+ result = subject.to_much_result(value: value1)
443
+ assert_that(result).is_the_same_as(subject)
444
+ assert_that(subject.value).equals(value1)
445
+ end
446
+ end
447
+ end