light-service 0.16.0 → 0.17.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: d41ecb22a4b0d3cd9779c1e5726c8f34e6f186a34f04ec97ea5928f682f08fd8
4
- data.tar.gz: 64f4d7f52607048313e9f39bea158899ef804deb32ae9744715e5969cc7b1567
3
+ metadata.gz: b37602f04d4539ba8d8622f9e226c916071760ee37e21c7add4e1972f9c5175f
4
+ data.tar.gz: f55175d1a477c78896522f4bdca07697ceb80c7b62fca80e4c6803ff06bb2ec7
5
5
  SHA512:
6
- metadata.gz: 2345b72e3d9581aecaea2fe5eca1bd3c538cdb0cfcd2d943ac021ca4f3ef31913ac4b06011944c017df330f3ee8dc385793e8185f3e79cba6c51fbe6ee6acba6
7
- data.tar.gz: 703b9608edfa42bf0d73135fa5b4eafa789e8a31c4239056fd8b7397d6f0a212f8c5c69d66834f1f5b9fe2431b234f8c0373ccaaa86f286d82671bfe8d8b705b
6
+ metadata.gz: d087df4f8d16b2e4f2611ac9e026906d2c7bb40cbe19b31052a71ed87e7ed5d70016bfc6ccfff363a4a04df7e9ff676c495d5246a7f69a142897cede456e99f4
7
+ data.tar.gz: 2317cff4254ae4bb6a20f481f042e2e63785fa015f130e4d01acb799f65e1e1db5f1f8fe1ebe9fdc973617925c456f8e4d024fe20ba0af98204a65a0c0f81b78
data/README.md CHANGED
@@ -21,6 +21,8 @@ LightService is a powerful and flexible service skeleton framework with an empha
21
21
  * [Skipping the Rest of the Actions](#skipping-the-rest-of-the-actions)
22
22
  * [Benchmarking Actions with Around Advice](#benchmarking-actions-with-around-advice)
23
23
  * [Before and After Action Hooks](#before-and-after-action-hooks)
24
+ * [Expects and Promises](#expects-and-promises)
25
+ * [Default values for optional Expected keys](#default-values-for-optional-expected-keys)
24
26
  * [Key Aliases](#key-aliases)
25
27
  * [Logging](#logging)
26
28
  * [Error Codes](#error-codes)
@@ -529,9 +531,11 @@ These ideas are originally from Aspect Oriented Programming, read more about the
529
531
  ## Expects and Promises
530
532
  The `expects` and `promises` macros are rules for the inputs/outputs of an action.
531
533
  `expects` describes what keys it needs to execute, and `promises` makes sure the keys are in the context after the
532
- action is reduced. If either of them are violated, a custom exception is thrown.
534
+ action is reduced. If either of them are violated, a `LightService::ExpectedKeysNotInContextError` or
535
+ `LightService::PromisedKeysNotInContextError` exception respectively will be thrown.
533
536
 
534
537
  This is how it's used:
538
+
535
539
  ```ruby
536
540
  class FooAction
537
541
  extend LightService::Action
@@ -539,46 +543,78 @@ class FooAction
539
543
  promises :bar
540
544
 
541
545
  executed do |context|
542
- baz = context.fetch :baz
543
-
544
- bar = baz + 2
545
- context[:bar] = bar
546
+ context.bar = context.baz + 2
546
547
  end
547
548
  end
548
549
  ```
549
550
 
550
- The `expects` macro does a bit more for you: it pulls the value with the expected key from the context, and
551
- makes it available to you through a reader. You can refactor the action like this:
551
+ The `expects` macro will pull the value with the expected key from the context, and
552
+ makes it available to you through a reader.
553
+
554
+ The `promises` macro will not only check if the context has the promised keys, it
555
+ also sets them for you in the context if you use the accessor with the same name,
556
+ much the same way as the expects macro works.
557
+
558
+ The context object is essentially a smarter-than-normal Hash. Take a look at [this spec](spec/action_expects_and_promises_spec.rb)
559
+ to see expects and promises used with and without accessors.
560
+
561
+ ### Default values for optional Expected keys
562
+
563
+ When you have an expected key that has a sensible default which should be used everywhere and
564
+ only overridden on an as-needed basis, you can specify a default value. An example use-case
565
+ is a flag that allows a failure from a service under most circumstances to avoid failing an
566
+ entire workflow because of a non-critical action.
567
+
568
+ LightService provides two mechanisms for specifying default values:
569
+
570
+ 1. A static value that is used as-is
571
+ 2. A callable that takes the current context as a param
572
+
573
+ Using the above use case, consider an action that sends a text message. In most cases,
574
+ if there is a problem sending the text message, it might be OK for it to fail. We will
575
+ `expect` an `allow_failure` key, but set it with a default, like so:
552
576
 
553
577
  ```ruby
554
- class FooAction
578
+ class SendSMS
555
579
  extend LightService::Action
556
- expects :baz
557
- promises :bar
580
+ expects :message, :user
581
+ expects :allow_failure, default: true
558
582
 
559
583
  executed do |context|
560
- bar = context.baz + 2
561
- context[:bar] = bar
584
+ sms_api = SMSService.new(key: ENV["SMS_API_KEY"])
585
+ status = sms_api.send(ctx.user.mobile_number, ctx.message)
586
+
587
+ if !status.sent_ok?
588
+ ctx.fail!(status.err_msg) unless ctx.allow_failure
589
+ end
562
590
  end
563
591
  end
564
592
  ```
565
593
 
566
- The `promises` macro will not only check if the context has the promised keys, it also sets it for you in the context if
567
- you use the accessor with the same name. The code above can be further simplified:
594
+ Default values can also be processed dynamically by providing a callable. Any values already
595
+ specified in the context are available to it via Hash key lookup syntax. e.g.
568
596
 
569
597
  ```ruby
570
- class FooAction
598
+ class SendSMS
571
599
  extend LightService::Action
572
- expects :baz
573
- promises :bar
600
+ expects :message, :user
601
+ expects :allow_failure, default: ->(ctx) { !ctx[:user].admin? } # Admins must always get SMS'
574
602
 
575
603
  executed do |context|
576
- context.bar = context.baz + 2
604
+ sms_api = SMSService.new(key: ENV["SMS_API_KEY"])
605
+ status = sms_api.send(ctx.user.mobile_number, ctx.message)
606
+
607
+ if !status.sent_ok?
608
+ ctx.fail!(status.err_msg) unless ctx.allow_failure
609
+ end
577
610
  end
578
611
  end
579
612
  ```
580
613
 
581
- Take a look at [this spec](spec/action_expects_and_promises_spec.rb) to see the refactoring in action.
614
+ **Note** that default values must be specified one at a time on their own line.
615
+
616
+ You can then call an action or organizer that uses an action with defaults without specifying
617
+ the expected key that has a default.
582
618
 
583
619
  ## Key Aliases
584
620
  The `aliases` macro sets up pairs of keys and aliases in an organizer. Actions can access the context using the aliases.
@@ -927,16 +963,19 @@ The 7 different orchestrator constructs an organizer can have:
927
963
 
928
964
  1. `reduce_until`
929
965
  2. `reduce_if`
930
- 3. `iterate`
931
- 4. `execute`
932
- 5. `with_callback`
933
- 6. `add_to_context`
934
- 7. `add_aliases`
966
+ 3. `reduce_if_else`
967
+ 4. `iterate`
968
+ 5. `execute`
969
+ 6. `with_callback`
970
+ 7. `add_to_context`
971
+ 8. `add_aliases`
935
972
 
936
973
  `reduce_until` behaves like a while loop in imperative languages, it iterates until the provided predicate in the lambda evaluates to true. Take a look at [this acceptance test](spec/acceptance/organizer/reduce_until_spec.rb) to see how it's used.
937
974
 
938
975
  `reduce_if` will reduce the included organizers and/or actions if the predicate in the lambda evaluates to true. [This acceptance test](spec/acceptance/organizer/reduce_if_spec.rb) describes this functionality.
939
976
 
977
+ `reduce_if_else` takes three arguments, a condition lambda, a first set of "if true" steps, and a second set of "if false" steps. If the lambda evaluates to true, the "if true" steps are executed, otherwise the "else steps" are executed. [This acceptance test](spec/acceptance/organizer/reduce_if_else_spec.rb) describes this functionality.
978
+
940
979
  `iterate` gives your iteration logic, the symbol you define there has to be in the context as a key. For example, to iterate over items you will use `iterate(:items)` in your steps, the context needs to have `items` as a key, otherwise it will fail. The organizer will singularize the collection name and will put the actual item into the context under that name. Remaining with the example above, each element will be accessible by the name `item` for the actions in the `iterate` steps. [This acceptance test](spec/acceptance/organizer/iterate_spec.rb) should provide you with an example.
941
980
 
942
981
  To take advantage of another organizer or action, you might need to tweak the context a bit. Let's say you have a hash, and you need to iterate over its values in a series of action. To alter the context and have the values assigned into a variable, you need to create a new action with 1 line of code in it. That seems a lot of ceremony for a simple change. You can do that in a `execute` method like this `execute(->(ctx) { ctx[:some_values] = ctx.some_hash.values })`. [This test](spec/acceptance/organizer/execute_spec.rb) describes how you can use it.
@@ -1049,10 +1088,12 @@ When specifying `promises`, specs will be created testing for their existence af
1049
1088
 
1050
1089
  ## Other implementations
1051
1090
 
1052
- | Language | Repo | Author |
1053
- | :------- |:------------------------------------------------------------------| :------------------------------------------------------|
1054
- | Python | [pyservice](https://github.com/adomokos/pyservice) | [@adomokos](https://github.com/adomokos) |
1055
- | PHP | [light-service](https://github.com/douglasgreyling/light-service) | [@douglasgreyling](https://github.com/douglasgreyling) |
1091
+ | Language | Repo | Author |
1092
+ | :--------- |:------------------------------------------------------------------------| :------------------------------------------------------|
1093
+ | Python | [pyservice](https://github.com/adomokos/pyservice) | [@adomokos](https://github.com/adomokos) |
1094
+ | PHP | [light-service](https://github.com/douglasgreyling/light-service) | [@douglasgreyling](https://github.com/douglasgreyling) |
1095
+ | JavaScript | [light-service.js](https://github.com/douglasgreyling/light-service.js) | [@douglasgreyling](https://github.com/douglasgreyling) |
1096
+
1056
1097
 
1057
1098
  ## Contributing
1058
1099
  1. Fork it
data/RELEASES.md CHANGED
@@ -1,5 +1,11 @@
1
1
  A brief list of new features and changes introduced with the specified version.
2
2
 
3
+ ### 0.17.0
4
+ * [Fix around_action hook for nested actions](https://github.com/adomokos/light-service/pull/217)
5
+ * [Add ReduceIfElse macro](https://github.com/adomokos/light-service/pull/218)
6
+ * [Implement support for default values for optional expected keys](https://github.com/adomokos/light-service/pull/219)
7
+ * [Add light-service.js implementation to README](https://github.com/adomokos/light-service/pull/222)
8
+
3
9
  ### 0.16.0
4
10
  * [Drop Ruby 2.4 support](https://github.com/adomokos/light-service/pull/207)
5
11
  * [Fix callback current action](https://github.com/adomokos/light-service/pull/209)
@@ -15,6 +15,12 @@ module LightService
15
15
 
16
16
  module Macros
17
17
  def expects(*args)
18
+ if expect_key_having_default?(args)
19
+ available_defaults[args.first] = args.last[:default]
20
+
21
+ args = [args.first]
22
+ end
23
+
18
24
  expected_keys.concat(args)
19
25
  end
20
26
 
@@ -30,8 +36,8 @@ module LightService
30
36
  @promised_keys ||= []
31
37
  end
32
38
 
33
- def executed
34
- define_singleton_method :execute do |context = {}|
39
+ def executed(*_args, &block)
40
+ define_singleton_method :execute do |context = Context.make|
35
41
  action_context = create_action_context(context)
36
42
  return action_context if action_context.stop_processing?
37
43
 
@@ -43,7 +49,8 @@ module LightService
43
49
 
44
50
  catch(:jump_when_failed) do
45
51
  call_before_action(action_context)
46
- yield(action_context)
52
+
53
+ execute_action(action_context, &block)
47
54
 
48
55
  # Reset the stored action in case it was changed downstream
49
56
  action_context.current_action = self
@@ -66,8 +73,34 @@ module LightService
66
73
 
67
74
  private
68
75
 
76
+ def execute_action(context)
77
+ if around_action_context?(context)
78
+ context.around_actions.call(context) do
79
+ yield(context)
80
+ context
81
+ end
82
+ else
83
+ yield(context)
84
+ end
85
+ end
86
+
87
+ def available_defaults
88
+ @available_defaults ||= {}
89
+ end
90
+
91
+ def expect_key_having_default?(key)
92
+ return false unless key.size == 2 && key.last.is_a?(Hash)
93
+ return true if key.last.key?(:default)
94
+
95
+ bad_key = key.last.keys.first
96
+ err_msg = "Specify defaults with a `default` key. You have #{bad_key}."
97
+ raise UnusableExpectKeyDefaultError, err_msg
98
+ end
99
+
69
100
  def create_action_context(context)
70
- return context if context.is_a? LightService::Context
101
+ usable_defaults(context).each do |ctx_key, default|
102
+ context[ctx_key] = extract_default(default, context)
103
+ end
71
104
 
72
105
  LightService::Context.make(context)
73
106
  end
@@ -76,6 +109,22 @@ module LightService
76
109
  expected_keys + promised_keys
77
110
  end
78
111
 
112
+ def missing_expected_keys(context)
113
+ expected_keys - context.keys
114
+ end
115
+
116
+ def usable_defaults(context)
117
+ available_defaults.slice(
118
+ *(missing_expected_keys(context) & available_defaults.keys)
119
+ )
120
+ end
121
+
122
+ def extract_default(default, context)
123
+ return default unless default.respond_to?(:call)
124
+
125
+ default.call(context)
126
+ end
127
+
79
128
  def call_before_action(context)
80
129
  invoke_callbacks(context[:_before_actions], context)
81
130
  end
@@ -93,6 +142,11 @@ module LightService
93
142
 
94
143
  context
95
144
  end
145
+
146
+ def around_action_context?(context)
147
+ context.instance_of?(Context) &&
148
+ context.around_actions.respond_to?(:call)
149
+ end
96
150
  end
97
151
  end
98
152
  end
@@ -8,7 +8,8 @@ module LightService
8
8
 
9
9
  # rubocop:disable ClassLength
10
10
  class Context < Hash
11
- attr_accessor :message, :error_code, :current_action, :organized_by
11
+ attr_accessor :message, :error_code, :current_action, :around_actions,
12
+ :organized_by
12
13
 
13
14
  def initialize(context = {},
14
15
  outcome = Outcomes::SUCCESS,
@@ -3,4 +3,5 @@ module LightService
3
3
  class ExpectedKeysNotInContextError < StandardError; end
4
4
  class PromisedKeysNotInContextError < StandardError; end
5
5
  class ReservedKeysInContextError < StandardError; end
6
+ class UnusableExpectKeyDefaultError < StandardError; end
6
7
  end
@@ -0,0 +1,21 @@
1
+ module LightService
2
+ module Organizer
3
+ class ReduceIfElse
4
+ extend ScopedReducable
5
+
6
+ def self.run(organizer, condition_block, if_steps, else_steps)
7
+ lambda do |ctx|
8
+ return ctx if ctx.stop_processing?
9
+
10
+ ctx = if condition_block.call(ctx)
11
+ scoped_reduce(organizer, ctx, if_steps)
12
+ else
13
+ scoped_reduce(organizer, ctx, else_steps)
14
+ end
15
+
16
+ ctx
17
+ end
18
+ end
19
+ end
20
+ end
21
+ end
@@ -30,6 +30,7 @@ module LightService
30
30
  def reduce(*actions)
31
31
  raise "No action(s) were provided" if actions.empty?
32
32
 
33
+ @context.around_actions ||= around_each_handler
33
34
  actions.flatten!
34
35
 
35
36
  actions.each_with_object(context) do |action, current_context|
@@ -59,12 +60,10 @@ module LightService
59
60
  private
60
61
 
61
62
  def invoke_action(current_context, action)
62
- around_each_handler.call(current_context) do
63
- if action.respond_to?(:call)
64
- action.call(current_context)
65
- else
66
- action.execute(current_context)
67
- end
63
+ if action.respond_to?(:call)
64
+ action.call(current_context)
65
+ else
66
+ action.execute(current_context)
68
67
  end
69
68
  end
70
69
 
@@ -41,6 +41,10 @@ module LightService
41
41
  ReduceIf.run(self, condition_block, steps)
42
42
  end
43
43
 
44
+ def reduce_if_else(condition_block, if_steps, else_steps)
45
+ ReduceIfElse.run(self, condition_block, if_steps, else_steps)
46
+ end
47
+
44
48
  def reduce_until(condition_block, steps)
45
49
  ReduceUntil.run(self, condition_block, steps)
46
50
  end
@@ -1,3 +1,3 @@
1
1
  module LightService
2
- VERSION = "0.16.0".freeze
2
+ VERSION = "0.17.0".freeze
3
3
  end
data/lib/light-service.rb CHANGED
@@ -13,6 +13,7 @@ require 'light-service/organizer/with_reducer'
13
13
  require 'light-service/organizer/with_reducer_log_decorator'
14
14
  require 'light-service/organizer/with_reducer_factory'
15
15
  require 'light-service/organizer/reduce_if'
16
+ require 'light-service/organizer/reduce_if_else'
16
17
  require 'light-service/organizer/reduce_until'
17
18
  require 'light-service/organizer/iterate'
18
19
  require 'light-service/organizer/execute'
@@ -16,4 +16,19 @@ describe 'Executing arbitrary code around each action' do
16
16
  }]
17
17
  )
18
18
  end
19
+
20
+ it 'logs data with nested actions' do
21
+ context = { :number => 1, :logger => TestDoubles::TestLogger.new }
22
+
23
+ result = TestDoubles::AroundEachWithReduceIfOrganizer.call(context)
24
+
25
+ expect(result.fetch(:number)).to eq(7)
26
+ expect(result[:logger].logs).to eq(
27
+ [
28
+ { :action => TestDoubles::AddsOneAction, :before => 1, :after => 2 },
29
+ { :action => TestDoubles::AddsTwoAction, :before => 2, :after => 4 },
30
+ { :action => TestDoubles::AddsThreeAction, :before => 4, :after => 7 }
31
+ ]
32
+ )
33
+ end
19
34
  end
@@ -59,7 +59,7 @@ describe "Logs from organizer" do
59
59
  expect(log_message).to include(organizer_log_message)
60
60
  end
61
61
 
62
- it "lists the keys in contect after the actions are executed" do
62
+ it "lists the keys in context after the actions are executed" do
63
63
  organizer_log_message = "[LightService] - keys in context: " \
64
64
  ":tea, :milk, :coffee, :milk_tea, :latte"
65
65
  expect(log_message).to include(organizer_log_message)
@@ -0,0 +1,60 @@
1
+ require 'spec_helper'
2
+ require 'test_doubles'
3
+
4
+ RSpec.describe LightService::Organizer do
5
+ class TestReduceIfElse
6
+ extend LightService::Organizer
7
+
8
+ def self.call(context)
9
+ with(context).reduce(actions)
10
+ end
11
+
12
+ def self.actions
13
+ [
14
+ TestDoubles::AddsOneAction,
15
+ reduce_if_else(
16
+ ->(ctx) { ctx.number == 1 },
17
+ [TestDoubles::AddsOneAction],
18
+ [TestDoubles::AddsTwoAction]
19
+ )
20
+ ]
21
+ end
22
+ end
23
+
24
+ let(:empty_context) { LightService::Context.make }
25
+
26
+ it 'reduces the if_steps if the condition is true' do
27
+ result = TestReduceIfElse.call(:number => 0)
28
+
29
+ expect(result).to be_success
30
+ expect(result[:number]).to eq(2)
31
+ end
32
+
33
+ it 'reduces the else_steps if the condition is false' do
34
+ result = TestReduceIfElse.call(:number => 2)
35
+
36
+ expect(result).to be_success
37
+ expect(result[:number]).to eq(5)
38
+ end
39
+
40
+ it 'will not reduce over a failed context' do
41
+ empty_context.fail!('Something bad happened')
42
+
43
+ result = TestReduceIfElse.call(empty_context)
44
+
45
+ expect(result).to be_failure
46
+ end
47
+
48
+ it 'does not reduce over a skipped context' do
49
+ empty_context.skip_remaining!('No more needed')
50
+
51
+ result = TestReduceIfElse.call(empty_context)
52
+ expect(result).to be_success
53
+ end
54
+
55
+ it "knows that it's being conditionally reduced from within an organizer" do
56
+ result = TestReduceIfElse.call(:number => 2)
57
+
58
+ expect(result.organized_by).to eq TestReduceIfElse
59
+ end
60
+ end
@@ -0,0 +1,82 @@
1
+ require 'spec_helper'
2
+ require 'test_doubles'
3
+
4
+ describe ":expects macro using defaults" do
5
+ context "when all expected keys are supplied" do
6
+ it "is expected to ignore default values" do
7
+ outcome = TestDoubles::AddsNumbersWithOptionalDefaults.execute(
8
+ :first_number => 3,
9
+ :second_number => 5,
10
+ :third_number => 7
11
+ )
12
+
13
+ expect(outcome.total).to eq 15
14
+ end
15
+ end
16
+
17
+ context "when defaults are supplied" do
18
+ it "is expected to use static values" do
19
+ outcome = TestDoubles::AddsNumbersWithOptionalDefaults.execute(
20
+ :first_number => 3,
21
+ :second_number => 7
22
+ )
23
+
24
+ expect(outcome.total).to eq 20
25
+ end
26
+
27
+ it "is expected to use dynamic values" do
28
+ outcome = TestDoubles::AddsNumbersWithOptionalDefaults.execute(
29
+ :first_number => 3,
30
+ :third_number => 5
31
+ )
32
+
33
+ expect(outcome.total).to eq 18
34
+ end
35
+
36
+ it "is expected to process defaults in their defined order" do
37
+ outcome = TestDoubles::AddsNumbersWithOptionalDefaults.execute(
38
+ :third_number => 5,
39
+ :first_number => 3
40
+ )
41
+
42
+ expect(outcome.total).to eq 18
43
+ end
44
+
45
+ it "is expected to use all defaults if required" do
46
+ outcome = TestDoubles::AddsNumbersWithOptionalDefaults.execute(
47
+ :first_number => 3
48
+ )
49
+
50
+ expect(outcome.total).to eq 23
51
+ end
52
+ end
53
+
54
+ context "when used within an organizer" do
55
+ it "is expected to process required defaults" do
56
+ outcome = TestDoubles::OrganizerWithActionsUsingDefaults.call
57
+
58
+ expect(outcome.total).to eq 20
59
+ end
60
+ end
61
+
62
+ context "when defaults are misconfigured" do
63
+ it "is expected to raise an exception" do
64
+ expect do
65
+ # Needs to be specified in the block
66
+ # as error is raised at define time
67
+ class AddsNumbersWithIncorrectDefaults
68
+ extend LightService::Action
69
+
70
+ expects :first, :default => 10 # This one is fine. Other two arent
71
+ expects :second, :defalut => ->(ctx) { ctx[:first] + 7 }
72
+ expects :third, :deafult => 10
73
+ promises :total
74
+
75
+ executed do |ctx|
76
+ ctx.total = ctx.first + ctx.second + ctx.third
77
+ end
78
+ end
79
+ end.to raise_error(LightService::UnusableExpectKeyDefaultError)
80
+ end
81
+ end
82
+ end
data/spec/test_doubles.rb CHANGED
@@ -74,6 +74,16 @@ module TestDoubles
74
74
  end
75
75
  end
76
76
 
77
+ class AroundEachWithReduceIfOrganizer
78
+ extend LightService::Organizer
79
+
80
+ def self.call(action_arguments)
81
+ with(action_arguments)
82
+ .around_each(AroundEachLoggerHandler)
83
+ .reduce(ReduceIfOrganizer.actions)
84
+ end
85
+ end
86
+
77
87
  class AddsTwoActionWithFetch
78
88
  extend LightService::Action
79
89
 
@@ -566,6 +576,33 @@ module TestDoubles
566
576
  end
567
577
  end
568
578
 
579
+ class AddsNumbersWithOptionalDefaults
580
+ extend LightService::Action
581
+
582
+ expects :first_number
583
+ expects :second_number, :default => ->(ctx) { ctx[:first_number] + 7 }
584
+ expects :third_number, :default => 10
585
+ promises :total
586
+
587
+ executed do |ctx|
588
+ ctx.total = ctx.first_number + ctx.second_number + ctx.third_number
589
+ end
590
+ end
591
+
592
+ class OrganizerWithActionsUsingDefaults
593
+ extend LightService::Organizer
594
+ def self.call
595
+ with(:first_number => 1, :number => 1).reduce(actions)
596
+ end
597
+
598
+ def self.actions
599
+ [
600
+ AddsNumbersWithOptionalDefaults,
601
+ AddToTotalAction
602
+ ]
603
+ end
604
+ end
605
+
569
606
  class AnOrganizerThatAddsToContext
570
607
  extend LightService::Organizer
571
608
  def self.call
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: light-service
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.16.0
4
+ version: 0.17.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Attila Domokos
8
- autorequire:
8
+ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2021-07-05 00:00:00.000000000 Z
11
+ date: 2021-09-14 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activesupport
@@ -190,6 +190,7 @@ files:
190
190
  - lib/light-service/organizer/execute.rb
191
191
  - lib/light-service/organizer/iterate.rb
192
192
  - lib/light-service/organizer/reduce_if.rb
193
+ - lib/light-service/organizer/reduce_if_else.rb
193
194
  - lib/light-service/organizer/reduce_until.rb
194
195
  - lib/light-service/organizer/scoped_reducable.rb
195
196
  - lib/light-service/organizer/verify_call_method_exists.rb
@@ -229,6 +230,7 @@ files:
229
230
  - spec/acceptance/organizer/execute_spec.rb
230
231
  - spec/acceptance/organizer/execute_with_add_to_context_spec.rb
231
232
  - spec/acceptance/organizer/iterate_spec.rb
233
+ - spec/acceptance/organizer/reduce_if_else_spec.rb
232
234
  - spec/acceptance/organizer/reduce_if_spec.rb
233
235
  - spec/acceptance/organizer/reduce_until_spec.rb
234
236
  - spec/acceptance/organizer/with_callback_spec.rb
@@ -237,6 +239,7 @@ files:
237
239
  - spec/acceptance/testing/context_factory_spec.rb
238
240
  - spec/action_expected_keys_spec.rb
239
241
  - spec/action_expects_and_promises_spec.rb
242
+ - spec/action_optional_expected_keys_spec.rb
240
243
  - spec/action_promised_keys_spec.rb
241
244
  - spec/action_spec.rb
242
245
  - spec/context/inspect_spec.rb
@@ -270,7 +273,7 @@ homepage: https://github.com/adomokos/light-service
270
273
  licenses:
271
274
  - MIT
272
275
  metadata: {}
273
- post_install_message:
276
+ post_install_message:
274
277
  rdoc_options: []
275
278
  require_paths:
276
279
  - lib
@@ -285,8 +288,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
285
288
  - !ruby/object:Gem::Version
286
289
  version: '0'
287
290
  requirements: []
288
- rubygems_version: 3.1.2
289
- signing_key:
291
+ rubygems_version: 3.1.6
292
+ signing_key:
290
293
  specification_version: 4
291
294
  summary: A service skeleton with an emphasis on simplicity
292
295
  test_files:
@@ -314,6 +317,7 @@ test_files:
314
317
  - spec/acceptance/organizer/execute_spec.rb
315
318
  - spec/acceptance/organizer/execute_with_add_to_context_spec.rb
316
319
  - spec/acceptance/organizer/iterate_spec.rb
320
+ - spec/acceptance/organizer/reduce_if_else_spec.rb
317
321
  - spec/acceptance/organizer/reduce_if_spec.rb
318
322
  - spec/acceptance/organizer/reduce_until_spec.rb
319
323
  - spec/acceptance/organizer/with_callback_spec.rb
@@ -322,6 +326,7 @@ test_files:
322
326
  - spec/acceptance/testing/context_factory_spec.rb
323
327
  - spec/action_expected_keys_spec.rb
324
328
  - spec/action_expects_and_promises_spec.rb
329
+ - spec/action_optional_expected_keys_spec.rb
325
330
  - spec/action_promised_keys_spec.rb
326
331
  - spec/action_spec.rb
327
332
  - spec/context/inspect_spec.rb