dry-transaction 0.13.0 → 0.13.1
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/CHANGELOG.md +308 -0
- data/LICENSE +20 -0
- data/README.md +15 -41
- data/dry-transaction.gemspec +35 -0
- data/lib/dry-transaction.rb +2 -0
- data/lib/dry/transaction.rb +2 -0
- data/lib/dry/transaction/builder.rb +6 -4
- data/lib/dry/transaction/callable.rb +5 -0
- data/lib/dry/transaction/dsl.rb +2 -0
- data/lib/dry/transaction/errors.rb +2 -0
- data/lib/dry/transaction/instance_methods.rb +6 -4
- data/lib/dry/transaction/operation.rb +5 -3
- data/lib/dry/transaction/operation_resolver.rb +2 -0
- data/lib/dry/transaction/result_matcher.rb +3 -1
- data/lib/dry/transaction/stack.rb +2 -0
- data/lib/dry/transaction/step.rb +6 -4
- data/lib/dry/transaction/step_adapter.rb +6 -4
- data/lib/dry/transaction/step_adapters.rb +9 -7
- data/lib/dry/transaction/step_adapters/around.rb +4 -2
- data/lib/dry/transaction/step_adapters/check.rb +2 -0
- data/lib/dry/transaction/step_adapters/map.rb +2 -0
- data/lib/dry/transaction/step_adapters/raw.rb +5 -3
- data/lib/dry/transaction/step_adapters/tee.rb +2 -0
- data/lib/dry/transaction/step_adapters/try.rb +3 -1
- data/lib/dry/transaction/step_failure.rb +2 -0
- data/lib/dry/transaction/version.rb +3 -1
- metadata +14 -110
- data/Gemfile +0 -15
- data/Gemfile.lock +0 -97
- data/LICENSE.md +0 -9
- data/Rakefile +0 -6
- data/spec/examples.txt +0 -88
- data/spec/integration/around_spec.rb +0 -120
- data/spec/integration/auto_injection_spec.rb +0 -32
- data/spec/integration/custom_step_adapters_spec.rb +0 -41
- data/spec/integration/operation_spec.rb +0 -30
- data/spec/integration/passing_step_arguments_spec.rb +0 -51
- data/spec/integration/publishing_step_events_spec.rb +0 -119
- data/spec/integration/transaction_spec.rb +0 -573
- data/spec/integration/transaction_without_steps_spec.rb +0 -101
- data/spec/spec_helper.rb +0 -116
- data/spec/support/container.rb +0 -10
- data/spec/support/database.rb +0 -12
- data/spec/support/db_transactions.rb +0 -45
- data/spec/support/result_mixin.rb +0 -3
- data/spec/support/test_module_constants.rb +0 -11
- data/spec/unit/step_adapters/around_spec.rb +0 -46
- data/spec/unit/step_adapters/check_spec.rb +0 -43
- data/spec/unit/step_adapters/map_spec.rb +0 -16
- data/spec/unit/step_adapters/raw_spec.rb +0 -36
- data/spec/unit/step_adapters/tee_spec.rb +0 -17
- data/spec/unit/step_adapters/try_spec.rb +0 -89
- data/spec/unit/step_spec.rb +0 -139
@@ -1,573 +0,0 @@
|
|
1
|
-
RSpec.describe "Transactions" do
|
2
|
-
include_context "database"
|
3
|
-
|
4
|
-
include Dry::Monads::Result::Mixin
|
5
|
-
|
6
|
-
let(:dependencies) { {} }
|
7
|
-
|
8
|
-
before do
|
9
|
-
container.instance_exec do
|
10
|
-
register :process, -> input { {name: input["name"], email: input["email"]} }
|
11
|
-
register :verify, -> input { Success(input) }
|
12
|
-
register :validate, -> input { input[:email].nil? ? raise(Test::NotValidError, "email required") : input }
|
13
|
-
register :persist, -> input { self[:database] << input and true }
|
14
|
-
end
|
15
|
-
end
|
16
|
-
|
17
|
-
context "successful" do
|
18
|
-
let(:transaction) {
|
19
|
-
Class.new do
|
20
|
-
include Dry::Transaction(container: Test::Container)
|
21
|
-
map :process, with: :process
|
22
|
-
step :verify, with: :verify
|
23
|
-
try :validate, with: :validate, catch: Test::NotValidError
|
24
|
-
tee :persist, with: :persist
|
25
|
-
end.new(**dependencies)
|
26
|
-
}
|
27
|
-
let(:input) { {"name" => "Jane", "email" => "jane@doe.com"} }
|
28
|
-
|
29
|
-
it "calls the operations" do
|
30
|
-
transaction.call(input)
|
31
|
-
expect(database).to include(name: "Jane", email: "jane@doe.com")
|
32
|
-
end
|
33
|
-
|
34
|
-
it "returns a success" do
|
35
|
-
expect(transaction.call(input)).to be_a Dry::Monads::Result::Success
|
36
|
-
end
|
37
|
-
|
38
|
-
it "wraps the result of the final operation" do
|
39
|
-
expect(transaction.call(input).value!).to eq(name: "Jane", email: "jane@doe.com")
|
40
|
-
end
|
41
|
-
|
42
|
-
it "can be called multiple times to the same effect" do
|
43
|
-
transaction.call(input)
|
44
|
-
transaction.call(input)
|
45
|
-
|
46
|
-
expect(database[0]).to eql(name: "Jane", email: "jane@doe.com")
|
47
|
-
expect(database[1]).to eql(name: "Jane", email: "jane@doe.com")
|
48
|
-
end
|
49
|
-
|
50
|
-
it "supports matching on success" do
|
51
|
-
results = []
|
52
|
-
|
53
|
-
transaction.call(input) do |m|
|
54
|
-
m.success do |value|
|
55
|
-
results << "success for #{value[:email]}"
|
56
|
-
end
|
57
|
-
|
58
|
-
m.failure { }
|
59
|
-
end
|
60
|
-
|
61
|
-
expect(results.first).to eq "success for jane@doe.com"
|
62
|
-
end
|
63
|
-
end
|
64
|
-
|
65
|
-
context "different step names" do
|
66
|
-
before do
|
67
|
-
class Test::ContainerNames
|
68
|
-
extend Dry::Container::Mixin
|
69
|
-
register :process_step, -> input { {name: input["name"], email: input["email"]} }
|
70
|
-
register :verify_step, -> input { Dry::Monads::Success(input) }
|
71
|
-
register :persist_step, -> input { Test::DB << input and true }
|
72
|
-
end
|
73
|
-
end
|
74
|
-
|
75
|
-
let(:transaction) {
|
76
|
-
Class.new do
|
77
|
-
include Dry::Transaction(container: Test::ContainerNames)
|
78
|
-
|
79
|
-
map :process, with: :process_step
|
80
|
-
step :verify, with: :verify_step
|
81
|
-
tee :persist, with: :persist_step
|
82
|
-
end.new(**dependencies)
|
83
|
-
}
|
84
|
-
|
85
|
-
it "supports steps using differently named container operations" do
|
86
|
-
transaction.call("name" => "Jane", "email" => "jane@doe.com")
|
87
|
-
expect(database).to include(name: "Jane", email: "jane@doe.com")
|
88
|
-
end
|
89
|
-
end
|
90
|
-
|
91
|
-
describe "operation injection" do
|
92
|
-
let(:transaction) {
|
93
|
-
Class.new do
|
94
|
-
include Dry::Transaction(container: Test::Container)
|
95
|
-
map :process, with: :process
|
96
|
-
step :verify_step, with: :verify
|
97
|
-
tee :persist, with: :persist
|
98
|
-
end.new(**dependencies)
|
99
|
-
}
|
100
|
-
|
101
|
-
let(:dependencies) {
|
102
|
-
{verify_step: -> input { Success(input.merge(foo: :bar)) }}
|
103
|
-
}
|
104
|
-
|
105
|
-
it "calls injected operations" do
|
106
|
-
transaction.call("name" => "Jane", "email" => "jane@doe.com")
|
107
|
-
|
108
|
-
expect(database).to include(name: "Jane", email: "jane@doe.com", foo: :bar)
|
109
|
-
end
|
110
|
-
end
|
111
|
-
|
112
|
-
context "wrapping operations with local methods" do
|
113
|
-
let(:transaction) do
|
114
|
-
Class.new do
|
115
|
-
include Dry::Transaction(container: Test::Container)
|
116
|
-
|
117
|
-
map :process, with: :process
|
118
|
-
step :verify, with: :verify
|
119
|
-
tee :persist, with: :persist
|
120
|
-
|
121
|
-
def verify(input)
|
122
|
-
new_input = input.merge(greeting: "hello!")
|
123
|
-
super(new_input)
|
124
|
-
end
|
125
|
-
end.new(**dependencies)
|
126
|
-
end
|
127
|
-
|
128
|
-
let(:dependencies) { {} }
|
129
|
-
|
130
|
-
it "allows local methods to run operations via super" do
|
131
|
-
transaction.call("name" => "Jane", "email" => "jane@doe.com")
|
132
|
-
|
133
|
-
expect(database).to include(name: "Jane", email: "jane@doe.com", greeting: "hello!")
|
134
|
-
end
|
135
|
-
end
|
136
|
-
|
137
|
-
context "wrapping operations with private local methods" do
|
138
|
-
let(:transaction) do
|
139
|
-
Class.new do
|
140
|
-
include Dry::Transaction(container: Test::Container)
|
141
|
-
|
142
|
-
map :process, with: :process
|
143
|
-
step :verify, with: :verify
|
144
|
-
tee :persist, with: :persist
|
145
|
-
|
146
|
-
private
|
147
|
-
|
148
|
-
def verify(input)
|
149
|
-
new_input = input.merge(greeting: "hello!")
|
150
|
-
super(new_input)
|
151
|
-
end
|
152
|
-
end.new(**dependencies)
|
153
|
-
end
|
154
|
-
|
155
|
-
it "allows local methods to run operations via super" do
|
156
|
-
transaction.call("name" => "Jane", "email" => "jane@doe.com")
|
157
|
-
|
158
|
-
expect(database).to include(name: "Jane", email: "jane@doe.com", greeting: "hello!")
|
159
|
-
end
|
160
|
-
end
|
161
|
-
|
162
|
-
context "operation injection of step only defined in the transaction class not in the container" do
|
163
|
-
let(:transaction) do
|
164
|
-
Class.new do
|
165
|
-
include Dry::Transaction
|
166
|
-
|
167
|
-
step :process
|
168
|
-
|
169
|
-
def process(input)
|
170
|
-
new_input = input << :world
|
171
|
-
super(new_input)
|
172
|
-
end
|
173
|
-
end.new(**dependencies)
|
174
|
-
end
|
175
|
-
|
176
|
-
let(:dependencies) do
|
177
|
-
{process: -> input { Failure(input)} }
|
178
|
-
end
|
179
|
-
|
180
|
-
# FIXME: needs a better description
|
181
|
-
it "execute the transaction and execute the injected operation" do
|
182
|
-
result = transaction.call([:hello])
|
183
|
-
|
184
|
-
expect(result).to eq Failure([:hello])
|
185
|
-
end
|
186
|
-
end
|
187
|
-
|
188
|
-
context "operation injection of step without container and no transaction instance methods" do
|
189
|
-
let(:transaction) do
|
190
|
-
Class.new do
|
191
|
-
include Dry::Transaction
|
192
|
-
|
193
|
-
map :process
|
194
|
-
step :verify
|
195
|
-
try :validate, catch: Test::NotValidError
|
196
|
-
tee :persist
|
197
|
-
|
198
|
-
end.new(**dependencies)
|
199
|
-
end
|
200
|
-
|
201
|
-
let(:dependencies) do
|
202
|
-
{
|
203
|
-
process: -> input { {name: input["name"], email: input["email"]} },
|
204
|
-
verify: -> input { Success(input) },
|
205
|
-
validate: -> input { input[:email].nil? ? raise(Test::NotValidError, "email required") : input },
|
206
|
-
persist: -> input { database << input and true }
|
207
|
-
}
|
208
|
-
end
|
209
|
-
|
210
|
-
let(:input) { {"name" => "Jane", "email" => "jane@doe.com"} }
|
211
|
-
|
212
|
-
it "calls the injected operations" do
|
213
|
-
transaction.call(input)
|
214
|
-
expect(database).to include(name: "Jane", email: "jane@doe.com")
|
215
|
-
end
|
216
|
-
end
|
217
|
-
|
218
|
-
context "operation injection of step without container and no transaction instance methods but missing an injected operation" do
|
219
|
-
let(:transaction) do
|
220
|
-
Class.new do
|
221
|
-
include Dry::Transaction
|
222
|
-
|
223
|
-
map :process
|
224
|
-
step :verify
|
225
|
-
try :validate, catch: Test::NotValidError
|
226
|
-
tee :persist
|
227
|
-
|
228
|
-
end.new(**dependencies)
|
229
|
-
end
|
230
|
-
|
231
|
-
let(:dependencies) do
|
232
|
-
{
|
233
|
-
process: -> input { {name: input["name"], email: input["email"]} },
|
234
|
-
verify: -> input { Success(input) },
|
235
|
-
validate: -> input { input[:email].nil? ? raise(Test::NotValidError, "email required") : input }
|
236
|
-
}
|
237
|
-
end
|
238
|
-
|
239
|
-
let(:input) { {"name" => "Jane", "email" => "jane@doe.com"} }
|
240
|
-
|
241
|
-
it "raises an exception" do
|
242
|
-
expect { transaction }.to raise_error(Dry::Transaction::MissingStepError)
|
243
|
-
end
|
244
|
-
end
|
245
|
-
|
246
|
-
context "local step definition" do
|
247
|
-
let(:transaction) do
|
248
|
-
Class.new do
|
249
|
-
include Dry::Transaction(container: Test::Container)
|
250
|
-
|
251
|
-
map :process, with: :process
|
252
|
-
step :verify
|
253
|
-
tee :persist, with: :persist
|
254
|
-
|
255
|
-
def verify(input)
|
256
|
-
Success(input.keys)
|
257
|
-
end
|
258
|
-
end.new
|
259
|
-
end
|
260
|
-
|
261
|
-
it "execute step only defined as local method" do
|
262
|
-
transaction.call("name" => "Jane", "email" => "jane@doe.com")
|
263
|
-
|
264
|
-
expect(database).to include([:name, :email])
|
265
|
-
end
|
266
|
-
end
|
267
|
-
|
268
|
-
context "local step definition not in container" do
|
269
|
-
let(:transaction) do
|
270
|
-
Class.new do
|
271
|
-
include Dry::Transaction(container: Test::Container)
|
272
|
-
|
273
|
-
map :process, with: :process
|
274
|
-
step :verify_only_local
|
275
|
-
tee :persist, with: :persist
|
276
|
-
|
277
|
-
def verify_only_local(input)
|
278
|
-
Success(input.keys)
|
279
|
-
end
|
280
|
-
end.new
|
281
|
-
end
|
282
|
-
|
283
|
-
it "execute step only defined as local method" do
|
284
|
-
transaction.call("name" => "Jane", "email" => "jane@doe.com")
|
285
|
-
|
286
|
-
expect(database).to include([:name, :email])
|
287
|
-
end
|
288
|
-
end
|
289
|
-
|
290
|
-
context "all steps are local methods" do
|
291
|
-
let(:transaction_class) do
|
292
|
-
Class.new do
|
293
|
-
include Dry::Transaction
|
294
|
-
|
295
|
-
map :process
|
296
|
-
step :verify
|
297
|
-
tee :persist
|
298
|
-
|
299
|
-
def process(input)
|
300
|
-
input.to_a
|
301
|
-
end
|
302
|
-
|
303
|
-
def verify(input)
|
304
|
-
Success(input)
|
305
|
-
end
|
306
|
-
|
307
|
-
def persist(input)
|
308
|
-
Test::Container[:database] << input and true
|
309
|
-
end
|
310
|
-
end
|
311
|
-
end
|
312
|
-
|
313
|
-
it "executes succesfully" do
|
314
|
-
transaction_class.new.call("name" => "Jane", "email" => "jane@doe.com")
|
315
|
-
expect(database).to include([["name", "Jane"], ["email", "jane@doe.com"]])
|
316
|
-
end
|
317
|
-
|
318
|
-
it "allows replacement steps to be injected" do
|
319
|
-
verify = -> { Failure("nope") }
|
320
|
-
|
321
|
-
result = transaction_class.new(verify: verify).("name" => "Jane", "email" => "jane@doe.com")
|
322
|
-
expect(result).to eq Failure("nope")
|
323
|
-
end
|
324
|
-
end
|
325
|
-
|
326
|
-
context "failed in a try step" do
|
327
|
-
let(:transaction) {
|
328
|
-
Class.new do
|
329
|
-
include Dry::Transaction(container: Test::Container)
|
330
|
-
map :process, with: :process
|
331
|
-
step :verify, with: :verify
|
332
|
-
try :validate, with: :validate, catch: Test::NotValidError
|
333
|
-
tee :persist, with: :persist
|
334
|
-
end.new(**dependencies)
|
335
|
-
}
|
336
|
-
let(:input) { {"name" => "Jane"} }
|
337
|
-
|
338
|
-
it "does not run subsequent operations" do
|
339
|
-
transaction.call(input)
|
340
|
-
expect(database).to be_empty
|
341
|
-
end
|
342
|
-
|
343
|
-
it "returns a failure" do
|
344
|
-
expect(transaction.call(input)).to be_a Dry::Monads::Result::Failure
|
345
|
-
end
|
346
|
-
|
347
|
-
it "wraps the result of the failing operation" do
|
348
|
-
expect(transaction.call(input).failure).to be_a Test::NotValidError
|
349
|
-
end
|
350
|
-
|
351
|
-
it "supports matching on failure" do
|
352
|
-
results = []
|
353
|
-
|
354
|
-
transaction.call(input) do |m|
|
355
|
-
m.success { }
|
356
|
-
|
357
|
-
m.failure do |value|
|
358
|
-
results << "Failed: #{value}"
|
359
|
-
end
|
360
|
-
end
|
361
|
-
|
362
|
-
expect(results.first).to eq "Failed: email required"
|
363
|
-
end
|
364
|
-
|
365
|
-
it "supports matching on specific step failures" do
|
366
|
-
results = []
|
367
|
-
|
368
|
-
transaction.call(input) do |m|
|
369
|
-
m.success { }
|
370
|
-
|
371
|
-
m.failure :validate do |value|
|
372
|
-
results << "Validation failure: #{value}"
|
373
|
-
end
|
374
|
-
end
|
375
|
-
|
376
|
-
expect(results.first).to eq "Validation failure: email required"
|
377
|
-
end
|
378
|
-
|
379
|
-
it "supports matching on un-named step failures" do
|
380
|
-
results = []
|
381
|
-
|
382
|
-
transaction.call(input) do |m|
|
383
|
-
m.success { }
|
384
|
-
|
385
|
-
m.failure :some_other_step do |value|
|
386
|
-
results << "Some other step failure"
|
387
|
-
end
|
388
|
-
|
389
|
-
m.failure do |value|
|
390
|
-
results << "Catch-all failure: #{value}"
|
391
|
-
end
|
392
|
-
end
|
393
|
-
|
394
|
-
expect(results.first).to eq "Catch-all failure: email required"
|
395
|
-
end
|
396
|
-
end
|
397
|
-
|
398
|
-
context "failed in a raw step" do
|
399
|
-
let(:input) { {"name" => "Jane", "email" => "jane@doe.com"} }
|
400
|
-
|
401
|
-
before do
|
402
|
-
class Test::ContainerRaw
|
403
|
-
extend Dry::Container::Mixin
|
404
|
-
extend Dry::Monads::Result::Mixin
|
405
|
-
register :process_step, -> input { {name: input["name"], email: input["email"]} }
|
406
|
-
register :verify_step, -> input { Failure("raw failure") }
|
407
|
-
register :persist_step, -> input { self[:database] << input and true }
|
408
|
-
end
|
409
|
-
end
|
410
|
-
|
411
|
-
let(:transaction) {
|
412
|
-
Class.new do
|
413
|
-
include Dry::Transaction(container: Test::ContainerRaw)
|
414
|
-
|
415
|
-
map :process, with: :process_step
|
416
|
-
step :verify, with: :verify_step
|
417
|
-
tee :persist, with: :persist_step
|
418
|
-
end.new(**dependencies)
|
419
|
-
}
|
420
|
-
|
421
|
-
it "does not run subsequent operations" do
|
422
|
-
transaction.call(input)
|
423
|
-
expect(database).to be_empty
|
424
|
-
end
|
425
|
-
|
426
|
-
it "returns a failure" do
|
427
|
-
expect(transaction.call(input)).to be_a_failure
|
428
|
-
end
|
429
|
-
|
430
|
-
it "returns the failing value from the operation" do
|
431
|
-
expect(transaction.call(input).failure).to eq "raw failure"
|
432
|
-
end
|
433
|
-
|
434
|
-
it "returns an object that quacks like expected" do
|
435
|
-
result = transaction.call(input).failure
|
436
|
-
|
437
|
-
expect(Array(result)).to eq(['raw failure'])
|
438
|
-
end
|
439
|
-
|
440
|
-
it "does not allow to call private methods on the result accidently" do
|
441
|
-
result = transaction.call(input).failure
|
442
|
-
|
443
|
-
expect { result.print('') }.to raise_error(NoMethodError)
|
444
|
-
end
|
445
|
-
end
|
446
|
-
|
447
|
-
context "non-confirming raw step result" do
|
448
|
-
let(:input) { {"name" => "Jane", "email" => "jane@doe.com"} }
|
449
|
-
|
450
|
-
let(:transaction) {
|
451
|
-
Class.new do
|
452
|
-
include Dry::Transaction(container: Test::ContainerRaw)
|
453
|
-
map :process
|
454
|
-
step :verify
|
455
|
-
tee :persist
|
456
|
-
end.new(**dependencies)
|
457
|
-
}
|
458
|
-
|
459
|
-
before do
|
460
|
-
class Test::ContainerRaw
|
461
|
-
extend Dry::Container::Mixin
|
462
|
-
register :process, -> input { {name: input["name"], email: input["email"]} }
|
463
|
-
register :verify, -> input { "failure" }
|
464
|
-
register :persist, -> input { Test::DB << input and true }
|
465
|
-
end
|
466
|
-
end
|
467
|
-
|
468
|
-
it "raises an exception" do
|
469
|
-
expect { transaction.call(input) }.to raise_error(ArgumentError)
|
470
|
-
end
|
471
|
-
end
|
472
|
-
|
473
|
-
context "keyword arguments" do
|
474
|
-
let(:input) { { name: 'jane', age: 20 } }
|
475
|
-
|
476
|
-
let(:upcaser) do
|
477
|
-
Class.new {
|
478
|
-
include Dry::Monads::Result::Mixin
|
479
|
-
|
480
|
-
def call(name: 'John', **rest)
|
481
|
-
Success(name: name[0].upcase + name[1..-1], **rest)
|
482
|
-
end
|
483
|
-
}.new
|
484
|
-
end
|
485
|
-
|
486
|
-
let(:transaction) do
|
487
|
-
Class.new {
|
488
|
-
include Dry::Transaction
|
489
|
-
|
490
|
-
step :camelize
|
491
|
-
|
492
|
-
}.new(camelize: upcaser)
|
493
|
-
end
|
494
|
-
|
495
|
-
it "calls the operations" do
|
496
|
-
expect(transaction.(input).value!).to eql(name: 'Jane', age: 20)
|
497
|
-
end
|
498
|
-
end
|
499
|
-
|
500
|
-
context "invalid steps" do
|
501
|
-
context "non-callable step" do
|
502
|
-
context "with container" do
|
503
|
-
let(:input) { {} }
|
504
|
-
|
505
|
-
let(:transaction) {
|
506
|
-
Class.new do
|
507
|
-
include Dry::Transaction(container: Test::ContainerRaw)
|
508
|
-
map :not_a_proc, with: :not_a_proc
|
509
|
-
end.new
|
510
|
-
}
|
511
|
-
|
512
|
-
before do
|
513
|
-
class Test::ContainerRaw
|
514
|
-
extend Dry::Container::Mixin
|
515
|
-
|
516
|
-
register :not_a_proc, "definitely not a proc"
|
517
|
-
end
|
518
|
-
end
|
519
|
-
|
520
|
-
it "raises an exception" do
|
521
|
-
expect { transaction.call(input) }.to raise_error(Dry::Transaction::InvalidStepError)
|
522
|
-
end
|
523
|
-
end
|
524
|
-
end
|
525
|
-
|
526
|
-
context "missing steps" do
|
527
|
-
context "no container" do
|
528
|
-
let(:input) { {} }
|
529
|
-
|
530
|
-
let(:transaction) {
|
531
|
-
Class.new do
|
532
|
-
include Dry::Transaction
|
533
|
-
map :noop
|
534
|
-
map :i_am_missing
|
535
|
-
|
536
|
-
def noop
|
537
|
-
Success(input)
|
538
|
-
end
|
539
|
-
end.new
|
540
|
-
}
|
541
|
-
|
542
|
-
it "raises an exception" do
|
543
|
-
expect { transaction.call(input) }.to raise_error(Dry::Transaction::MissingStepError)
|
544
|
-
end
|
545
|
-
end
|
546
|
-
|
547
|
-
context "with container" do
|
548
|
-
let(:input) { {} }
|
549
|
-
|
550
|
-
let(:transaction) {
|
551
|
-
Class.new do
|
552
|
-
include Dry::Transaction(container: Test::ContainerRaw)
|
553
|
-
map :noop
|
554
|
-
map :i_am_missing
|
555
|
-
|
556
|
-
end.new
|
557
|
-
}
|
558
|
-
|
559
|
-
before do
|
560
|
-
class Test::ContainerRaw
|
561
|
-
extend Dry::Container::Mixin
|
562
|
-
|
563
|
-
register :noop, -> input { Success(input) }
|
564
|
-
end
|
565
|
-
end
|
566
|
-
|
567
|
-
it "raises an exception" do
|
568
|
-
expect { transaction.call(input) }.to raise_error(Dry::Transaction::MissingStepError)
|
569
|
-
end
|
570
|
-
end
|
571
|
-
end
|
572
|
-
end
|
573
|
-
end
|