functional-light-service 0.2.4

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.
Files changed (110) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +22 -0
  3. data/.rspec +3 -0
  4. data/.rubocop.yml +72 -0
  5. data/.travis.yml +22 -0
  6. data/Appraisals +3 -0
  7. data/CHANGELOG.md +37 -0
  8. data/CODE_OF_CONDUCT.md +22 -0
  9. data/Gemfile +6 -0
  10. data/LICENSE +22 -0
  11. data/README.md +1424 -0
  12. data/Rakefile +12 -0
  13. data/VERSION +1 -0
  14. data/functional-light-service.gemspec +26 -0
  15. data/gemfiles/activesupport_5.gemfile +8 -0
  16. data/gemfiles/activesupport_5.gemfile.lock +82 -0
  17. data/lib/functional-light-service/action.rb +102 -0
  18. data/lib/functional-light-service/configuration.rb +24 -0
  19. data/lib/functional-light-service/context/key_verifier.rb +118 -0
  20. data/lib/functional-light-service/context.rb +165 -0
  21. data/lib/functional-light-service/errors.rb +6 -0
  22. data/lib/functional-light-service/functional/enum.rb +254 -0
  23. data/lib/functional-light-service/functional/maybe.rb +14 -0
  24. data/lib/functional-light-service/functional/monad.rb +66 -0
  25. data/lib/functional-light-service/functional/null.rb +74 -0
  26. data/lib/functional-light-service/functional/option.rb +99 -0
  27. data/lib/functional-light-service/functional/result.rb +122 -0
  28. data/lib/functional-light-service/localization_adapter.rb +44 -0
  29. data/lib/functional-light-service/organizer/execute.rb +14 -0
  30. data/lib/functional-light-service/organizer/iterate.rb +22 -0
  31. data/lib/functional-light-service/organizer/reduce_if.rb +17 -0
  32. data/lib/functional-light-service/organizer/reduce_until.rb +20 -0
  33. data/lib/functional-light-service/organizer/scoped_reducable.rb +13 -0
  34. data/lib/functional-light-service/organizer/verify_call_method_exists.rb +28 -0
  35. data/lib/functional-light-service/organizer/with_callback.rb +26 -0
  36. data/lib/functional-light-service/organizer/with_reducer.rb +71 -0
  37. data/lib/functional-light-service/organizer/with_reducer_factory.rb +18 -0
  38. data/lib/functional-light-service/organizer/with_reducer_log_decorator.rb +105 -0
  39. data/lib/functional-light-service/organizer.rb +105 -0
  40. data/lib/functional-light-service/testing/context_factory.rb +40 -0
  41. data/lib/functional-light-service/testing.rb +1 -0
  42. data/lib/functional-light-service/version.rb +3 -0
  43. data/lib/functional-light-service.rb +29 -0
  44. data/resources/fail_actions.png +0 -0
  45. data/resources/light-service.png +0 -0
  46. data/resources/organizer_and_actions.png +0 -0
  47. data/resources/skip_actions.png +0 -0
  48. data/spec/acceptance/add_numbers_spec.rb +11 -0
  49. data/spec/acceptance/after_actions_spec.rb +71 -0
  50. data/spec/acceptance/around_each_spec.rb +19 -0
  51. data/spec/acceptance/before_actions_spec.rb +98 -0
  52. data/spec/acceptance/custom_log_from_organizer_spec.rb +60 -0
  53. data/spec/acceptance/fail_spec.rb +24 -0
  54. data/spec/acceptance/include_warning_spec.rb +29 -0
  55. data/spec/acceptance/log_from_organizer_spec.rb +154 -0
  56. data/spec/acceptance/message_localization_spec.rb +118 -0
  57. data/spec/acceptance/not_having_call_method_warning_spec.rb +39 -0
  58. data/spec/acceptance/organizer/around_each_with_reduce_if_spec.rb +42 -0
  59. data/spec/acceptance/organizer/context_failure_and_skipping_spec.rb +65 -0
  60. data/spec/acceptance/organizer/execute_spec.rb +46 -0
  61. data/spec/acceptance/organizer/iterate_spec.rb +37 -0
  62. data/spec/acceptance/organizer/reduce_if_spec.rb +51 -0
  63. data/spec/acceptance/organizer/reduce_until_spec.rb +43 -0
  64. data/spec/acceptance/organizer/with_callback_spec.rb +110 -0
  65. data/spec/acceptance/rollback_spec.rb +132 -0
  66. data/spec/acceptance/skip_all_warning_spec.rb +20 -0
  67. data/spec/acceptance/testing/context_factory_spec.rb +54 -0
  68. data/spec/action_expected_keys_spec.rb +63 -0
  69. data/spec/action_expects_and_promises_spec.rb +93 -0
  70. data/spec/action_promised_keys_spec.rb +122 -0
  71. data/spec/action_spec.rb +89 -0
  72. data/spec/context/inspect_spec.rb +57 -0
  73. data/spec/context_spec.rb +197 -0
  74. data/spec/examples/amount_spec.rb +77 -0
  75. data/spec/examples/controller_spec.rb +63 -0
  76. data/spec/examples/validate_address_spec.rb +37 -0
  77. data/spec/lib/deterministic/class_mixin_spec.rb +24 -0
  78. data/spec/lib/deterministic/currify_spec.rb +88 -0
  79. data/spec/lib/deterministic/monad_axioms.rb +44 -0
  80. data/spec/lib/deterministic/monad_spec.rb +45 -0
  81. data/spec/lib/deterministic/null_spec.rb +58 -0
  82. data/spec/lib/deterministic/option_spec.rb +133 -0
  83. data/spec/lib/deterministic/result/failure_spec.rb +65 -0
  84. data/spec/lib/deterministic/result/result_map_spec.rb +154 -0
  85. data/spec/lib/deterministic/result/result_shared.rb +24 -0
  86. data/spec/lib/deterministic/result/success_spec.rb +41 -0
  87. data/spec/lib/deterministic/result_spec.rb +63 -0
  88. data/spec/lib/enum_spec.rb +112 -0
  89. data/spec/localization_adapter_spec.rb +83 -0
  90. data/spec/organizer/with_reducer_spec.rb +56 -0
  91. data/spec/organizer_key_aliases_spec.rb +29 -0
  92. data/spec/organizer_spec.rb +93 -0
  93. data/spec/readme_spec.rb +47 -0
  94. data/spec/sample/calculates_order_tax_action_spec.rb +16 -0
  95. data/spec/sample/calculates_tax_spec.rb +30 -0
  96. data/spec/sample/looks_up_tax_percentage_action_spec.rb +53 -0
  97. data/spec/sample/provides_free_shipping_action_spec.rb +25 -0
  98. data/spec/sample/tax/calculates_order_tax_action.rb +9 -0
  99. data/spec/sample/tax/calculates_tax.rb +11 -0
  100. data/spec/sample/tax/looks_up_tax_percentage_action.rb +27 -0
  101. data/spec/sample/tax/provides_free_shipping_action.rb +10 -0
  102. data/spec/spec_helper.rb +24 -0
  103. data/spec/support.rb +1 -0
  104. data/spec/test_doubles.rb +552 -0
  105. data/spec/testing/context_factory/iterate_spec.rb +39 -0
  106. data/spec/testing/context_factory/reduce_if_spec.rb +40 -0
  107. data/spec/testing/context_factory/reduce_until_spec.rb +40 -0
  108. data/spec/testing/context_factory/with_callback_spec.rb +38 -0
  109. data/spec/testing/context_factory_spec.rb +55 -0
  110. metadata +285 -0
@@ -0,0 +1,24 @@
1
+ $LOAD_PATH << File.join(File.dirname(__FILE__), '..', 'lib')
2
+ $LOAD_PATH << File.join(File.dirname(__FILE__))
3
+
4
+ if ENV['RUN_COVERAGE_REPORT']
5
+ require 'simplecov'
6
+
7
+ SimpleCov.start do
8
+ add_filter 'vendor/'
9
+ add_filter %r{^/spec/}
10
+ end
11
+
12
+ SimpleCov.minimum_coverage_by_file 90
13
+ end
14
+
15
+ require 'functional-light-service'
16
+ require 'functional-light-service/testing'
17
+ require "functional-light-service/functional/null"
18
+ require 'ostruct'
19
+ require 'pry'
20
+ require 'support'
21
+ require 'test_doubles'
22
+ require 'stringio'
23
+
24
+ I18n.enforce_available_locales = true
data/spec/support.rb ADDED
@@ -0,0 +1 @@
1
+
@@ -0,0 +1,552 @@
1
+ # A collection of Action and Organizer dummies used in specs
2
+
3
+ module TestDoubles
4
+ class RollbackAction
5
+ extend FunctionalLightService::Action
6
+ executed(&:fail_with_rollback!)
7
+ end
8
+
9
+ class RaiseErrorAction
10
+ extend FunctionalLightService::Action
11
+ executed do |_ctx|
12
+ raise 'A problem has occured.'
13
+ end
14
+ end
15
+
16
+ class RaiseAnotherErrorAction
17
+ extend FunctionalLightService::Action
18
+ executed do |_ctx|
19
+ raise 'More problems'
20
+ end
21
+ end
22
+
23
+ class SkipAllAction
24
+ extend FunctionalLightService::Action
25
+ executed(&:skip_remaining!)
26
+ end
27
+
28
+ class FailureAction
29
+ extend FunctionalLightService::Action
30
+ executed(&:fail!)
31
+ end
32
+
33
+ class AddTwoOrganizer
34
+ extend FunctionalLightService::Organizer
35
+ def self.call(context)
36
+ with(context).reduce([AddsOneAction, AddsOneAction])
37
+ end
38
+ end
39
+
40
+ class AroundEachNullHandler
41
+ def self.call(_action)
42
+ yield
43
+ end
44
+ end
45
+
46
+ class TestLogger
47
+ attr_accessor :logs
48
+ def initialize
49
+ @logs = []
50
+ end
51
+ end
52
+
53
+ class AroundEachLoggerHandler
54
+ def self.call(context)
55
+ before_number = context[:number]
56
+ result = yield
57
+
58
+ context[:logger].logs << {
59
+ :action => context.current_action,
60
+ :before => before_number,
61
+ :after => result[:number]
62
+ }
63
+
64
+ result
65
+ end
66
+ end
67
+
68
+ class AroundEachOrganizer
69
+ extend FunctionalLightService::Organizer
70
+ def self.call(action_arguments)
71
+ with(action_arguments)
72
+ .around_each(AroundEachLoggerHandler)
73
+ .reduce([AddsTwoActionWithFetch])
74
+ end
75
+ end
76
+
77
+ class AddsTwoActionWithFetch
78
+ extend FunctionalLightService::Action
79
+
80
+ executed do |context|
81
+ number = context.fetch(:number, 0)
82
+ context[:number] = number + 2
83
+ end
84
+ end
85
+
86
+ class AnAction; end
87
+ class AnotherAction; end
88
+
89
+ class AnOrganizer
90
+ extend FunctionalLightService::Organizer
91
+
92
+ def self.call(action_arguments)
93
+ with(action_arguments).reduce([AnAction, AnotherAction])
94
+ end
95
+
96
+ def self.do_something_with_no_actions(action_arguments)
97
+ with(action_arguments).reduce
98
+ end
99
+
100
+ def self.do_something_with_no_starting_context
101
+ reduce([AnAction, AnotherAction])
102
+ end
103
+ end
104
+
105
+ class NotExplicitlyReturningContextOrganizer
106
+ extend FunctionalLightService::Organizer
107
+
108
+ def self.call(context)
109
+ context[:foo] = [1, 2, 3]
110
+ end
111
+ end
112
+
113
+ class NestingOrganizer
114
+ extend FunctionalLightService::Organizer
115
+
116
+ def self.call(context)
117
+ with(context).reduce(actions)
118
+ end
119
+
120
+ def self.actions
121
+ [NotExplicitlyReturningContextOrganizer, NestedAction]
122
+ end
123
+ end
124
+
125
+ class NestedAction
126
+ extend FunctionalLightService::Action
127
+
128
+ expects :foo
129
+
130
+ executed do |context|
131
+ context[:bar] = context.foo
132
+ end
133
+ end
134
+
135
+ class MakesTeaWithMilkAction
136
+ extend FunctionalLightService::Action
137
+ expects :tea, :milk
138
+ promises :milk_tea
139
+
140
+ executed do |context|
141
+ context.milk_tea = "#{context.tea} - #{context.milk}"
142
+ end
143
+ end
144
+
145
+ class MultipleExpectsAction
146
+ extend FunctionalLightService::Action
147
+ expects :tea
148
+ expects :milk, :chocolate
149
+ promises :milk_tea
150
+
151
+ executed do |context|
152
+ context.milk_tea = "#{context.tea} - #{context.milk}"\
153
+ " - with #{context.chocolate}"
154
+ end
155
+ end
156
+
157
+ class MakesCappuccinoAction
158
+ extend FunctionalLightService::Action
159
+ expects :coffee, :milk
160
+ promises :cappuccino
161
+ end
162
+
163
+ class MakesLatteAction
164
+ extend FunctionalLightService::Action
165
+ expects :coffee, :milk
166
+ promises :latte
167
+
168
+ executed do |context|
169
+ context[:latte] = "#{context.coffee} - with lots of #{context.milk}"
170
+ case context.milk
171
+ when :very_hot then
172
+ context.fail!("Can't make a latte from a milk that's very hot!")
173
+ when :super_hot then
174
+ context.fail_with_rollback!("Can't make a latte from a milk that's super hot!")
175
+ when "5%" then
176
+ context.skip_remaining!("Can't make a latte with a fatty milk like that!")
177
+ next context
178
+ end
179
+ end
180
+ end
181
+
182
+ class MultiplePromisesAction
183
+ extend FunctionalLightService::Action
184
+ expects :coffee, :milk
185
+ promises :cappuccino
186
+ promises :latte
187
+
188
+ executed do |context|
189
+ context.cappuccino = "Cappucino needs #{context.coffee} and a little milk"
190
+ context.latte = "Latte needs #{context.coffee} and a lot of milk"
191
+ end
192
+ end
193
+
194
+ class MakesTeaAndCappuccino
195
+ extend FunctionalLightService::Organizer
196
+
197
+ def self.call(tea, milk, coffee)
198
+ with(:tea => tea, :milk => milk, :coffee => coffee)
199
+ .reduce(TestDoubles::MakesTeaWithMilkAction,
200
+ TestDoubles::MakesLatteAction)
201
+ end
202
+ end
203
+
204
+ class MakesCappuccinoAddsTwo
205
+ extend FunctionalLightService::Organizer
206
+
207
+ def self.call(milk, coffee)
208
+ with(:milk => milk, :coffee => coffee)
209
+ .reduce(TestDoubles::AddsTwoActionWithFetch,
210
+ TestDoubles::MakesLatteAction)
211
+ end
212
+ end
213
+
214
+ class MakesCappuccinoAddsTwoAndFails
215
+ extend FunctionalLightService::Organizer
216
+
217
+ def self.call(coffee, this_hot = :very_hot)
218
+ with(:milk => this_hot, :coffee => coffee)
219
+ .reduce(TestDoubles::MakesLatteAction,
220
+ TestDoubles::AddsTwoActionWithFetch)
221
+ end
222
+ end
223
+
224
+ class MakesCappuccinoSkipsAddsTwo
225
+ extend FunctionalLightService::Organizer
226
+
227
+ def self.call(coffee)
228
+ with(:milk => "5%", :coffee => coffee)
229
+ .reduce(TestDoubles::MakesLatteAction,
230
+ TestDoubles::AddsTwoActionWithFetch)
231
+ end
232
+ end
233
+
234
+ class AdditionOrganizer
235
+ extend FunctionalLightService::Organizer
236
+
237
+ def self.call(number)
238
+ with(:number => number).reduce(actions)
239
+ end
240
+
241
+ def self.actions
242
+ [
243
+ AddsOneAction,
244
+ AddsTwoAction,
245
+ AddsThreeAction
246
+ ]
247
+ end
248
+ end
249
+
250
+ class ExtraArgumentAdditionOrganizer
251
+ extend FunctionalLightService::Organizer
252
+
253
+ def self.call(number, another_number)
254
+ with(:number => number + another_number).reduce(actions)
255
+ end
256
+
257
+ def self.actions
258
+ [
259
+ AddsOneAction,
260
+ AddsTwoAction,
261
+ AddsThreeAction
262
+ ]
263
+ end
264
+ end
265
+
266
+ class AddsOne
267
+ extend FunctionalLightService::Organizer
268
+
269
+ def call(ctx)
270
+ with(ctx).reduce(actions)
271
+ end
272
+
273
+ def self.actions
274
+ [AddsOneAction]
275
+ end
276
+ end
277
+
278
+ class AddsOneAction
279
+ extend FunctionalLightService::Action
280
+ expects :number
281
+ promises :number
282
+
283
+ executed do |context|
284
+ context.number += 1
285
+ end
286
+ end
287
+
288
+ class AddsTwoAction
289
+ extend FunctionalLightService::Action
290
+ expects :number
291
+
292
+ executed do |context|
293
+ context.number += 2
294
+ end
295
+ end
296
+
297
+ class AddsThreeAction
298
+ extend FunctionalLightService::Action
299
+ expects :number
300
+
301
+ executed do |context|
302
+ context.number += 3
303
+ end
304
+ end
305
+
306
+ class IterateOrganizer
307
+ extend FunctionalLightService::Organizer
308
+
309
+ def self.call(ctx)
310
+ with(ctx).reduce(actions)
311
+ end
312
+
313
+ def self.actions
314
+ [
315
+ AddsOneIteratesAction,
316
+ iterate(:numbers, [
317
+ AddsTwoAction,
318
+ AddsThreeAction
319
+ ])
320
+ ]
321
+ end
322
+ end
323
+
324
+ class AddsOneIteratesAction
325
+ extend FunctionalLightService::Action
326
+ expects :numbers
327
+ promises :numbers
328
+
329
+ executed do |context|
330
+ context.numbers = context.numbers.map { |n| n + 1 }
331
+ end
332
+ end
333
+
334
+ class CallbackOrganizer
335
+ extend FunctionalLightService::Organizer
336
+
337
+ def self.call(ctx)
338
+ with(ctx).reduce(actions)
339
+ end
340
+
341
+ def self.actions
342
+ [
343
+ AddsOneAction,
344
+ with_callback(AddTenCallbackAction, [
345
+ AddsTwoAction,
346
+ AddsThreeAction
347
+ ])
348
+ ]
349
+ end
350
+ end
351
+
352
+ class AddTenCallbackAction
353
+ extend FunctionalLightService::Action
354
+ expects :number, :callback
355
+
356
+ executed do |context|
357
+ context.number += 10
358
+ context.number =
359
+ context.callback.call(context).fetch(:number)
360
+ end
361
+ end
362
+
363
+ class ReduceUntilOrganizer
364
+ extend FunctionalLightService::Organizer
365
+
366
+ def self.call(ctx)
367
+ with(ctx).reduce(actions)
368
+ end
369
+
370
+ def self.actions
371
+ [
372
+ AddsOneAction,
373
+ reduce_until(->(ctx) { ctx.number > 3 }, [
374
+ AddsTwoAction,
375
+ AddsThreeAction
376
+ ])
377
+ ]
378
+ end
379
+ end
380
+
381
+ class ReduceIfOrganizer
382
+ extend FunctionalLightService::Organizer
383
+
384
+ def self.call(ctx)
385
+ with(ctx).reduce(actions)
386
+ end
387
+
388
+ def self.actions
389
+ [
390
+ AddsOneAction,
391
+ reduce_if(->(ctx) { ctx.number > 1 }, [
392
+ AddsTwoAction,
393
+ AddsThreeAction
394
+ ])
395
+ ]
396
+ end
397
+ end
398
+
399
+ class MakesTeaExpectingReservedKey
400
+ extend FunctionalLightService::Action
401
+ expects :tea, :message
402
+
403
+ executed do |context|
404
+ context.product = context.number + 3
405
+ end
406
+ end
407
+
408
+ class MakesTeaExpectingMultipleReservedKeys
409
+ extend FunctionalLightService::Action
410
+ expects :tea, :message, :error_code, :current_action
411
+
412
+ executed do |context|
413
+ context.product = context.number + 3
414
+ end
415
+ end
416
+
417
+ class MakesTeaPromisingReservedKey
418
+ extend FunctionalLightService::Action
419
+ expects :tea
420
+ promises :product, :message
421
+
422
+ executed do |context|
423
+ context.product = context.number + 3
424
+ end
425
+ end
426
+
427
+ class MakesTeaPromisingMultipleReservedKeys
428
+ extend FunctionalLightService::Action
429
+ expects :tea
430
+ promises :product, :message, :error_code, :current_action
431
+
432
+ executed do |context|
433
+ context.product = context.number + 3
434
+ end
435
+ end
436
+
437
+ class MakesTeaPromisingKeyButRaisesException
438
+ extend FunctionalLightService::Action
439
+ promises :product
440
+
441
+ executed do |context|
442
+ context.product = make_product
443
+ end
444
+
445
+ def self.make_product
446
+ raise "Fail"
447
+ end
448
+ private_class_method :make_product
449
+ end
450
+
451
+ class PromisesPromisedKeyAction
452
+ extend FunctionalLightService::Action
453
+
454
+ promises :promised_key
455
+
456
+ executed do |ctx|
457
+ ctx.promised_key = "promised_key"
458
+ end
459
+ end
460
+
461
+ class ExpectsExpectedKeyAction
462
+ extend FunctionalLightService::Action
463
+
464
+ expects :expected_key
465
+ promises :final_key
466
+
467
+ executed do |ctx|
468
+ ctx.final_key = ctx.expected_key
469
+ end
470
+ end
471
+
472
+ class NullAction
473
+ extend FunctionalLightService::Action
474
+
475
+ executed { |_ctx| }
476
+ end
477
+
478
+ class TestIterate
479
+ extend FunctionalLightService::Organizer
480
+
481
+ def self.call(context)
482
+ with(context)
483
+ .reduce([iterate(:counters,
484
+ [TestDoubles::AddsOneAction])])
485
+ end
486
+
487
+ def self.call_single(context)
488
+ with(context)
489
+ .reduce([iterate(:counters,
490
+ TestDoubles::AddsOneAction)])
491
+ end
492
+ end
493
+
494
+ class TestWithCallback
495
+ extend FunctionalLightService::Organizer
496
+
497
+ def self.call(context = {})
498
+ with(context).reduce(actions)
499
+ end
500
+
501
+ def self.actions
502
+ [
503
+ SetUpContextAction,
504
+ with_callback(IterateCollectionAction,
505
+ [IncrementCountAction,
506
+ AddToTotalAction])
507
+ ]
508
+ end
509
+ end
510
+
511
+ class SetUpContextAction
512
+ extend FunctionalLightService::Action
513
+ promises :numbers, :counter, :total
514
+
515
+ executed do |ctx|
516
+ ctx.numbers = [1, 2, 3]
517
+ ctx.counter = 0
518
+ ctx.total = 0
519
+ end
520
+ end
521
+
522
+ class IterateCollectionAction
523
+ extend FunctionalLightService::Action
524
+ expects :numbers, :callback
525
+ promises :number
526
+
527
+ executed do |ctx|
528
+ ctx.numbers.each do |number|
529
+ ctx.number = number
530
+ ctx.callback.call(ctx)
531
+ end
532
+ end
533
+ end
534
+
535
+ class IncrementCountAction
536
+ extend FunctionalLightService::Action
537
+ expects :counter
538
+
539
+ executed do |ctx|
540
+ ctx.counter = ctx.counter + 1
541
+ end
542
+ end
543
+
544
+ class AddToTotalAction
545
+ extend FunctionalLightService::Action
546
+ expects :number, :total
547
+
548
+ executed do |ctx|
549
+ ctx.total += ctx.number
550
+ end
551
+ end
552
+ end
@@ -0,0 +1,39 @@
1
+ require 'spec_helper'
2
+ require 'test_doubles'
3
+
4
+ RSpec.describe 'ContextFactory - used with IterateOrganizer' do
5
+ let(:organizer) { TestDoubles::IterateOrganizer }
6
+
7
+ context 'when called with outside iterate steps' do
8
+ it 'creates a context up-to the action defined before the iteration' do
9
+ ctx =
10
+ FunctionalLightService::Testing::ContextFactory
11
+ .make_from(organizer)
12
+ .for(TestDoubles::AddsOneIteratesAction)
13
+ .with(:numbers => [1, 2])
14
+
15
+ expect(ctx[:numbers]).to eq([1, 2])
16
+ end
17
+
18
+ it 'creates a context up-to iteration with empty context steps' do
19
+ ctx =
20
+ FunctionalLightService::Testing::ContextFactory
21
+ .make_from(organizer)
22
+ .for(TestDoubles::AddsTwoAction)
23
+ .with(:numbers => [1, 2])
24
+
25
+ expect(ctx.numbers).to eq([2, 3])
26
+ end
27
+
28
+ it 'creates a context only to the first step of the iteration' do
29
+ ctx =
30
+ FunctionalLightService::Testing::ContextFactory
31
+ .make_from(organizer)
32
+ .for(TestDoubles::AddsThreeAction)
33
+ .with(:numbers => [1, 2])
34
+
35
+ expect(ctx.numbers).to eq([2, 3])
36
+ expect(ctx.number).to eq(4)
37
+ end
38
+ end
39
+ end
@@ -0,0 +1,40 @@
1
+ require 'spec_helper'
2
+ require 'test_doubles'
3
+
4
+ RSpec.describe 'ContextFactory - used with ReduceIfOrganizer' do
5
+ let(:organizer) { TestDoubles::ReduceIfOrganizer }
6
+
7
+ context 'when called with a truthy argument action' do
8
+ it 'executes a context up-to the callback action' do
9
+ ctx =
10
+ FunctionalLightService::Testing::ContextFactory
11
+ .make_from(organizer)
12
+ .for(TestDoubles::AddsThreeAction)
13
+ .with(:number => 1)
14
+
15
+ expect(ctx.number).to eq(4)
16
+ end
17
+
18
+ it 'creates a context up-to action with empty context steps' do
19
+ ctx =
20
+ FunctionalLightService::Testing::ContextFactory
21
+ .make_from(organizer)
22
+ .for(TestDoubles::AddsTwoAction)
23
+ .with(:number => 1)
24
+
25
+ expect(ctx.number).to eq(2)
26
+ end
27
+ end
28
+
29
+ context 'when called with a false argument action' do
30
+ it 'does not execute the steps' do
31
+ ctx =
32
+ FunctionalLightService::Testing::ContextFactory
33
+ .make_from(organizer)
34
+ .for(TestDoubles::AddsThreeAction)
35
+ .with(:number => 0)
36
+
37
+ expect(ctx.number).to eq(1)
38
+ end
39
+ end
40
+ end
@@ -0,0 +1,40 @@
1
+ require 'spec_helper'
2
+ require 'test_doubles'
3
+
4
+ RSpec.describe 'ContextFactory - used with ReduceUntilOrganizer' do
5
+ let(:organizer) { TestDoubles::ReduceUntilOrganizer }
6
+
7
+ context 'when called with truthy block' do
8
+ it 'creates a context up-to the action defined before the iteration' do
9
+ ctx =
10
+ FunctionalLightService::Testing::ContextFactory
11
+ .make_from(organizer)
12
+ .for(TestDoubles::AddsTwoAction)
13
+ .with(:number => 1)
14
+
15
+ expect(ctx[:number]).to eq(2)
16
+ end
17
+
18
+ it 'creates a context only to the first step of the loop' do
19
+ ctx =
20
+ FunctionalLightService::Testing::ContextFactory
21
+ .make_from(organizer)
22
+ .for(TestDoubles::AddsThreeAction)
23
+ .with(:number => 1)
24
+
25
+ expect(ctx.number).to eq(4)
26
+ end
27
+ end
28
+
29
+ context 'when called with falsey block' do
30
+ it 'creates a context up-to the first step' do
31
+ ctx =
32
+ FunctionalLightService::Testing::ContextFactory
33
+ .make_from(organizer)
34
+ .for(TestDoubles::AddsThreeAction)
35
+ .with(:number => 7)
36
+
37
+ expect(ctx[:number]).to eq(10)
38
+ end
39
+ end
40
+ end