functional-light-service 0.2.4

Sign up to get free protection for your applications and to get access to all the features.
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