light-service 0.17.0 → 0.19.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (50) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/project-build.yml +3 -6
  3. data/.rubocop.yml +117 -3
  4. data/README.md +101 -31
  5. data/RELEASES.md +11 -0
  6. data/lib/generators/light_service/generator_utils.rb +0 -2
  7. data/lib/light-service/action.rb +3 -5
  8. data/lib/light-service/configuration.rb +10 -2
  9. data/lib/light-service/context/key_verifier.rb +4 -2
  10. data/lib/light-service/context.rb +10 -15
  11. data/lib/light-service/deprecation_warning.rb +17 -0
  12. data/lib/light-service/errors.rb +4 -0
  13. data/lib/light-service/i18n/localization_adapter.rb +46 -0
  14. data/lib/light-service/localization_adapter.rb +14 -27
  15. data/lib/light-service/localization_map.rb +7 -0
  16. data/lib/light-service/orchestrator.rb +3 -3
  17. data/lib/light-service/organizer/reduce_case.rb +48 -0
  18. data/lib/light-service/organizer/verify_call_method_exists.rb +1 -1
  19. data/lib/light-service/organizer/with_reducer.rb +6 -8
  20. data/lib/light-service/organizer/with_reducer_log_decorator.rb +2 -2
  21. data/lib/light-service/organizer.rb +5 -3
  22. data/lib/light-service/testing/context_factory.rb +4 -0
  23. data/lib/light-service/version.rb +1 -1
  24. data/lib/light-service.rb +5 -2
  25. data/light-service.gemspec +3 -6
  26. data/spec/acceptance/after_actions_spec.rb +3 -9
  27. data/spec/acceptance/before_actions_spec.rb +3 -9
  28. data/spec/acceptance/include_warning_spec.rb +2 -2
  29. data/spec/acceptance/message_localization_spec.rb +7 -7
  30. data/spec/acceptance/not_having_call_method_warning_spec.rb +3 -3
  31. data/spec/acceptance/organizer/reduce_case_spec.rb +53 -0
  32. data/spec/acceptance/organizer/reduce_if_spec.rb +2 -0
  33. data/spec/acceptance/skip_all_warning_spec.rb +1 -1
  34. data/spec/context/inspect_spec.rb +5 -21
  35. data/spec/context_spec.rb +2 -2
  36. data/spec/i18n_localization_adapter_spec.rb +83 -0
  37. data/spec/lib/generators/action_generator_advanced_spec.rb +1 -1
  38. data/spec/lib/generators/action_generator_simple_spec.rb +1 -1
  39. data/spec/lib/generators/organizer_generator_advanced_spec.rb +1 -1
  40. data/spec/lib/generators/organizer_generator_simple_spec.rb +1 -1
  41. data/spec/localization_adapter_spec.rb +17 -38
  42. data/spec/sample/calculates_tax_spec.rb +0 -1
  43. data/spec/sample/looks_up_tax_percentage_action_spec.rb +3 -1
  44. data/spec/support.rb +1 -1
  45. data/spec/test_doubles.rb +20 -5
  46. data/spec/testing/context_factory_spec.rb +15 -0
  47. metadata +19 -42
  48. data/Appraisals +0 -11
  49. data/gemfiles/activesupport_5.gemfile +0 -7
  50. data/gemfiles/activesupport_6.gemfile +0 -7
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: b37602f04d4539ba8d8622f9e226c916071760ee37e21c7add4e1972f9c5175f
4
- data.tar.gz: f55175d1a477c78896522f4bdca07697ceb80c7b62fca80e4c6803ff06bb2ec7
3
+ metadata.gz: d569b02dd645032b8b5bf18aaaff2a571255cbb899b1c3975fb0f3708a740d4d
4
+ data.tar.gz: 41d774361e725cf016ecb5c168773a3e2cb0155b16fa4953b693c211cc77df22
5
5
  SHA512:
6
- metadata.gz: d087df4f8d16b2e4f2611ac9e026906d2c7bb40cbe19b31052a71ed87e7ed5d70016bfc6ccfff363a4a04df7e9ff676c495d5246a7f69a142897cede456e99f4
7
- data.tar.gz: 2317cff4254ae4bb6a20f481f042e2e63785fa015f130e4d01acb799f65e1e1db5f1f8fe1ebe9fdc973617925c456f8e4d024fe20ba0af98204a65a0c0f81b78
6
+ metadata.gz: 4b1e641b0136f71241bb047601b0003667ef1158d95635d7b70c57f301b6bb0faf313ecbc5a28b07dae7e139eb947460a2d5a78c9558c7e96ae773c6c025ef93
7
+ data.tar.gz: da0f8116260901f425c9829d1b4f97c990241ecbf693ac49696c1754313e7fe890ac7ad744a86740ff885c50aa373e4517843c29534ad9376c80c6b87e8df3b5
@@ -13,16 +13,13 @@ jobs:
13
13
  fail-fast: false
14
14
  matrix:
15
15
  os: [ubuntu, macos]
16
- ruby: [2.5.3, 2.6.6, 2.7.2]
17
- gemfile: [activesupport_5, activesupport_6]
16
+ ruby: ['3.1', '3.2', '3.3']
18
17
  continue-on-error: ${{ endsWith(matrix.ruby, 'head') || matrix.ruby == 'debug' }}
19
- env: # $BUNDLE_GEMFILE must be set at the job level, so it is set for all steps
20
- BUNDLE_GEMFILE: gemfiles/${{ matrix.gemfile }}.gemfile
21
18
  steps:
22
- - uses: actions/checkout@v2
19
+ - uses: actions/checkout@v3
23
20
  - uses: ruby/setup-ruby@v1
24
21
  with:
25
22
  ruby-version: ${{ matrix.ruby }}
26
- - run: bundle install
23
+ bundler-cache: true
27
24
  - run: bundle exec rspec spec
28
25
  - run: bundle exec rubocop
data/.rubocop.yml CHANGED
@@ -1,7 +1,7 @@
1
- require: rubocop-performance
1
+ # require: rubocop-performance
2
2
 
3
3
  AllCops:
4
- TargetRubyVersion: 2.3
4
+ TargetRubyVersion: 2.7
5
5
  Exclude:
6
6
  - 'lib/light-service.rb'
7
7
  - 'vendor/bundle/**/*'
@@ -47,8 +47,122 @@ Metrics/BlockLength:
47
47
  Exclude:
48
48
  - 'spec/**/*.rb'
49
49
 
50
- Layout/TrailingBlankLines:
50
+ Layout/TrailingEmptyLines:
51
51
  Enabled: false
52
52
 
53
53
  Layout/EndOfLine:
54
54
  EnforcedStyle: lf
55
+
56
+ Lint/ConstantDefinitionInBlock:
57
+ Exclude:
58
+ - 'spec/**/*.rb'
59
+
60
+ Lint/EmptyClass:
61
+ Exclude:
62
+ - 'spec/**/*.rb'
63
+
64
+ # Defaults after the Rubocop upgrade
65
+ Gemspec/DateAssignment: # new in 1.10
66
+ Enabled: true
67
+ Layout/LineEndStringConcatenationIndentation: # new in 1.18
68
+ Enabled: true
69
+ Layout/SpaceBeforeBrackets: # new in 1.7
70
+ Enabled: true
71
+ Lint/AmbiguousAssignment: # new in 1.7
72
+ Enabled: true
73
+ Lint/AmbiguousOperatorPrecedence: # new in 1.21
74
+ Enabled: true
75
+ Lint/AmbiguousRange: # new in 1.19
76
+ Enabled: true
77
+ Lint/DeprecatedConstants: # new in 1.8
78
+ Enabled: true
79
+ Lint/DuplicateBranch: # new in 1.3
80
+ Enabled: true
81
+ Lint/DuplicateRegexpCharacterClassElement: # new in 1.1
82
+ Enabled: true
83
+ Lint/EmptyBlock: # new in 1.1
84
+ Enabled: true
85
+ Lint/EmptyClass: # new in 1.3
86
+ Enabled: true
87
+ Lint/EmptyInPattern: # new in 1.16
88
+ Enabled: true
89
+ Lint/IncompatibleIoSelectWithFiberScheduler: # new in 1.21
90
+ Enabled: true
91
+ Lint/LambdaWithoutLiteralBlock: # new in 1.8
92
+ Enabled: true
93
+ Lint/NoReturnInBeginEndBlocks: # new in 1.2
94
+ Enabled: true
95
+ Lint/NumberedParameterAssignment: # new in 1.9
96
+ Enabled: true
97
+ Lint/OrAssignmentToConstant: # new in 1.9
98
+ Enabled: true
99
+ Lint/RedundantDirGlobSort: # new in 1.8
100
+ Enabled: true
101
+ Lint/SymbolConversion: # new in 1.9
102
+ Enabled: true
103
+ Lint/ToEnumArguments: # new in 1.1
104
+ Enabled: true
105
+ Lint/TripleQuotes: # new in 1.9
106
+ Enabled: true
107
+ Lint/UnexpectedBlockArity: # new in 1.5
108
+ Enabled: true
109
+ Lint/UnmodifiedReduceAccumulator: # new in 1.1
110
+ Enabled: true
111
+ Style/ArgumentsForwarding: # new in 1.1
112
+ Enabled: true
113
+ Style/CollectionCompact: # new in 1.2
114
+ Enabled: true
115
+ Style/DocumentDynamicEvalDefinition: # new in 1.1
116
+ Enabled: true
117
+ Style/EndlessMethod: # new in 1.8
118
+ Enabled: true
119
+ Style/HashConversion: # new in 1.10
120
+ Enabled: true
121
+ Style/HashExcept: # new in 1.7
122
+ Enabled: true
123
+ Style/IfWithBooleanLiteralBranches: # new in 1.9
124
+ Enabled: true
125
+ Style/InPatternThen: # new in 1.16
126
+ Enabled: true
127
+ Style/MultilineInPatternThen: # new in 1.16
128
+ Enabled: true
129
+ Style/NegatedIfElseCondition: # new in 1.2
130
+ Enabled: true
131
+ Style/NilLambda: # new in 1.3
132
+ Enabled: true
133
+ Style/QuotedSymbols: # new in 1.16
134
+ Enabled: true
135
+ Style/RedundantArgument: # new in 1.4
136
+ Enabled: true
137
+ Style/RedundantSelfAssignmentBranch: # new in 1.19
138
+ Enabled: true
139
+ Style/StringChars: # new in 1.12
140
+ Enabled: true
141
+ Style/SwapValues: # new in 1.1
142
+ Enabled: true
143
+ Gemspec/RequireMFA: # new in 1.23
144
+ Enabled: true
145
+ Lint/RequireRelativeSelfPath: # new in 1.22
146
+ Enabled: true
147
+ Lint/UselessRuby2Keywords: # new in 1.23
148
+ Enabled: true
149
+ Naming/BlockForwarding: # new in 1.24
150
+ Enabled: true
151
+ Security/IoMethods: # new in 1.22
152
+ Enabled: true
153
+ Style/FileRead: # new in 1.24
154
+ Enabled: true
155
+ Style/FileWrite: # new in 1.24
156
+ Enabled: true
157
+ Style/MapToHash: # new in 1.24
158
+ Enabled: true
159
+ Style/NestedFileDirname: # new in 1.26
160
+ Enabled: true
161
+ Style/NumberedParameters: # new in 1.22
162
+ Enabled: true
163
+ Style/NumberedParametersLimit: # new in 1.22
164
+ Enabled: true
165
+ Style/OpenStructUse: # new in 1.23
166
+ Enabled: true
167
+ Style/SelectByRegexp: # new in 1.22
168
+ Enabled: true
data/README.md CHANGED
@@ -10,29 +10,38 @@
10
10
  LightService is a powerful and flexible service skeleton framework with an emphasis on simplicity
11
11
 
12
12
  ## Table of Contents
13
- * [Why LightService?](#why-lightservice)
14
- * [Getting Started](#getting-started)
15
- * [Requirements](#requirements)
16
- * [Installation](#installation)
17
- * [Your first action](#your-first-action)
18
- * [Your first organizer](#your-first-organizer)
19
- * [Stopping the Series of Actions](#stopping-the-series-of-actions)
20
- * [Failing the Context](#failing-the-context)
21
- * [Skipping the Rest of the Actions](#skipping-the-rest-of-the-actions)
22
- * [Benchmarking Actions with Around Advice](#benchmarking-actions-with-around-advice)
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)
26
- * [Key Aliases](#key-aliases)
27
- * [Logging](#logging)
28
- * [Error Codes](#error-codes)
29
- * [Action Rollback](#action-rollback)
30
- * [Localizing Messages](#localizing-messages)
31
- * [Orchestrating Logic in Organizers](#orchestrating-logic-in-organizers)
32
- * [ContextFactory for Faster Action Testing](#contextfactory-for-faster-action-testing)
33
- * [Rails support](#rails-support)
34
- * [Implementations in other languages](#other-implementations)
35
- * [Contributing](#contributing)
13
+ - [Table of Contents](#table-of-contents)
14
+ - [Why LightService?](#why-lightservice)
15
+ - [Getting started](#getting-started)
16
+ - [Requirements](#requirements)
17
+ - [Installation](#installation)
18
+ - [Your first action](#your-first-action)
19
+ - [Your first organizer](#your-first-organizer)
20
+ - [Stopping the Series of Actions](#stopping-the-series-of-actions)
21
+ - [Failing the Context](#failing-the-context)
22
+ - [Skipping the rest of the actions](#skipping-the-rest-of-the-actions)
23
+ - [Benchmarking Actions with Around Advice](#benchmarking-actions-with-around-advice)
24
+ - [Before and After Action Hooks](#before-and-after-action-hooks)
25
+ - [Expects and Promises](#expects-and-promises)
26
+ - [Default values for optional Expected keys](#default-values-for-optional-expected-keys)
27
+ - [Key Aliases](#key-aliases)
28
+ - [Logging](#logging)
29
+ - [Error Codes](#error-codes)
30
+ - [Action Rollback](#action-rollback)
31
+ - [Localizing Messages](#localizing-messages)
32
+ - [Built-in localization adapter](#built-in-localization-adapter)
33
+ - [I18n localization adapter](#i18n-localization-adapter)
34
+ - [Custom localization adapter](#custom-localization-adapter)
35
+ - [Orchestrating Logic in Organizers](#orchestrating-logic-in-organizers)
36
+ - [ContextFactory for Faster Action Testing](#contextfactory-for-faster-action-testing)
37
+ - [Rails support](#rails-support)
38
+ - [Organizer generation](#organizer-generation)
39
+ - [Action generation](#action-generation)
40
+ - [Advanced action generation](#advanced-action-generation)
41
+ - [Other implementations](#other-implementations)
42
+ - [Contributing](#contributing)
43
+ - [Release Notes](#release-notes)
44
+ - [License](#license)
36
45
 
37
46
  ## Why LightService?
38
47
 
@@ -823,7 +832,61 @@ end
823
832
  ```
824
833
 
825
834
  ## Localizing Messages
826
- By default LightService provides a mechanism for easily translating your error or success messages via I18n. You can also provide your own custom localization adapter if your application's logic is more complex than what is shown here.
835
+
836
+ ### Built-in localization adapter
837
+
838
+ The built-in adapter simply uses a manually created dictionary to search for translations.
839
+
840
+ ```ruby
841
+ # lib/light_service_translations.rb
842
+ LightService::LocalizationMap.instance[:en] = {
843
+ :foo_action => {
844
+ :light_service => {
845
+ :failures => {
846
+ :exceeded_api_limit => "API limit for service Foo reached. Please try again later."
847
+ },
848
+ :successes => {
849
+ :yay => "Yaaay!"
850
+ }
851
+ }
852
+ }
853
+ }
854
+ ```
855
+
856
+ ```ruby
857
+ class FooAction
858
+ extend LightService::Action
859
+
860
+ executed do |context|
861
+ unless service_call.success?
862
+ context.fail!(:exceeded_api_limit)
863
+
864
+ # The failure message used here equates to:
865
+ # LightService::LocalizationMap.instance[:en][:foo_action][:light_service][:failures][:exceeded_api_limit]
866
+ end
867
+ end
868
+ end
869
+ ```
870
+
871
+ Nested classes will work too: `App::FooAction`, for example, would be translated to `app/foo_action` hash key.
872
+
873
+ `:en` is the default locale, but you can switch it whenever you want with
874
+
875
+ ```ruby
876
+ LightService::Configuration.locale = :it
877
+ ```
878
+
879
+ If you have `I18n` loaded in your project the default adapter will automatically be updated to use it.
880
+ But would you want to opt for the built-in localization adapter you can force it with
881
+
882
+ ```ruby
883
+ LightService::Configuration.localization_adapter = LightService::LocalizationAdapter
884
+ ```
885
+
886
+ ### I18n localization adapter
887
+
888
+ If `I18n` is loaded into your project, LightService will automatically provide a mechanism for easily translating your error or success messages via `I18n`.
889
+
827
890
 
828
891
  ```ruby
829
892
  class FooAction
@@ -881,13 +944,17 @@ module PaymentGateway
881
944
  end
882
945
  ```
883
946
 
947
+ ### Custom localization adapter
948
+
949
+ You can also provide your own custom localization adapter if your application's logic is more complex than what is shown here.
950
+
884
951
  To provide your own custom adapter, use the configuration setting and subclass the default adapter LightService provides.
885
952
 
886
953
  ```ruby
887
954
  LightService::Configuration.localization_adapter = MyLocalizer.new
888
955
 
889
956
  # lib/my_localizer.rb
890
- class MyLocalizer < LightService::LocalizationAdapter
957
+ class MyLocalizer < LightService::I18n::LocalizationAdapter
891
958
 
892
959
  # I just want to change the default lookup path
893
960
  # => "light_service.failures.payment_gateway/capture_funds"
@@ -959,16 +1026,17 @@ end
959
1026
 
960
1027
  This code is much easier to reason about, it's less noisy and it captures the goal of LightService well: simple, declarative code that's easy to understand.
961
1028
 
962
- The 7 different orchestrator constructs an organizer can have:
1029
+ The 9 different orchestrator constructs an organizer can have:
963
1030
 
964
1031
  1. `reduce_until`
965
1032
  2. `reduce_if`
966
1033
  3. `reduce_if_else`
967
- 4. `iterate`
968
- 5. `execute`
969
- 6. `with_callback`
970
- 7. `add_to_context`
971
- 8. `add_aliases`
1034
+ 4. `reduce_case`
1035
+ 5. `iterate`
1036
+ 6. `execute`
1037
+ 7. `with_callback`
1038
+ 8. `add_to_context`
1039
+ 9. `add_aliases`
972
1040
 
973
1041
  `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.
974
1042
 
@@ -976,6 +1044,8 @@ The 7 different orchestrator constructs an organizer can have:
976
1044
 
977
1045
  `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
1046
 
1047
+ `reduce_case` behaves like a Ruby `case` statement. The first parameter `value` is the key of the value within the context that will be worked with. The second parameter `when` is a hash where the keys are conditional values and the values are steps to take if the condition matches. The final parameter `else` is a set of steps to take if no conditions within the `when` parameter are met. [This acceptance test](spec/acceptance/organizer/reduce_case_spec.rb) describes this functionality.
1048
+
979
1049
  `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.
980
1050
 
981
1051
  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.
data/RELEASES.md CHANGED
@@ -1,5 +1,16 @@
1
1
  A brief list of new features and changes introduced with the specified version.
2
2
 
3
+ ### 0.19.0
4
+ * [Implement built-in localization adapter](https://github.com/adomokos/light-service/pull/238)
5
+ * [Swap ActiveSupport::Deprecation with built-in LightSupport::Deprecation](https://github.com/adomokos/light-service/pull/241)
6
+ * [Remove Active Support dependency](https://github.com/adomokos/light-service/pull/246)
7
+
8
+ ### 0.18.0
9
+ * [Remove Ruby 2.6, add 3.1 to build](https://github.com/adomokos/light-service/pull/233)
10
+ * [Add reduce_when](https://github.com/adomokos/light-service/pull/232)
11
+ * [Drop Ruby 2.5 version support, add 3.0 build](https://github.com/adomokos/light-service/pull/225)
12
+ * [Support for named argument in Ruby](https://github.com/adomokos/light-service/pull/224)
13
+
3
14
  ### 0.17.0
4
15
  * [Fix around_action hook for nested actions](https://github.com/adomokos/light-service/pull/217)
5
16
  * [Add ReduceIfElse macro](https://github.com/adomokos/light-service/pull/218)
@@ -25,7 +25,6 @@ module LightService
25
25
  options.tests? && test_framework_supported?
26
26
  end
27
27
 
28
- # rubocop:disable Metrics/AbcSize
29
28
  def create_required_gen_vals_from(name)
30
29
  path_parts = name.underscore.split('/')
31
30
 
@@ -39,7 +38,6 @@ module LightService
39
38
  :full_class_name => name.classify
40
39
  }
41
40
  end
42
- # rubocop:enable Metrics/AbcSize
43
41
  end
44
42
  end
45
43
  end
@@ -1,5 +1,3 @@
1
- require 'active_support/deprecation'
2
-
3
1
  module LightService
4
2
  module Action
5
3
  def self.extended(base_class)
@@ -7,9 +5,9 @@ module LightService
7
5
  end
8
6
 
9
7
  def self.included(base_class)
10
- msg = "including LightService::Action is deprecated. " \
11
- "Please use `extend LightService::Action` instead"
12
- ActiveSupport::Deprecation.warn(msg)
8
+ warning_msg = "including LightService::Action is deprecated. " \
9
+ "Please use `extend LightService::Action` instead"
10
+ LightService::Deprecation.warn(warning_msg)
13
11
  base_class.extend Macros
14
12
  end
15
13
 
@@ -2,14 +2,22 @@ module LightService
2
2
  class Configuration
3
3
  class << self
4
4
  attr_accessor :capture_errors
5
- attr_writer :logger, :localization_adapter
5
+ attr_writer :logger, :localization_adapter, :locale
6
6
 
7
7
  def logger
8
8
  @logger ||= _default_logger
9
9
  end
10
10
 
11
11
  def localization_adapter
12
- @localization_adapter ||= LocalizationAdapter.new
12
+ @localization_adapter ||= if Module.const_defined?('I18n')
13
+ LightService::I18n::LocalizationAdapter.new
14
+ else
15
+ LocalizationAdapter.new
16
+ end
17
+ end
18
+
19
+ def locale
20
+ @locale ||= :en
13
21
  end
14
22
 
15
23
  private
@@ -24,7 +24,7 @@ module LightService
24
24
 
25
25
  def error_message
26
26
  "#{type_name} #{format_keys(keys_not_found(keys))} " \
27
- "to be in the context during #{action}"
27
+ "to be in the context during #{action}"
28
28
  end
29
29
 
30
30
  def throw_error_predicate(_keys)
@@ -95,7 +95,7 @@ module LightService
95
95
 
96
96
  def error_message
97
97
  "promised or expected keys cannot be a " \
98
- "reserved key: [#{format_keys(violated_keys)}]"
98
+ "reserved key: [#{format_keys(violated_keys)}]"
99
99
  end
100
100
 
101
101
  def keys
@@ -116,9 +116,11 @@ module LightService
116
116
  end
117
117
 
118
118
  class ReservedKeysViaOrganizerVerifier < ReservedKeysVerifier
119
+ # rubocop:disable Lint/MissingSuper
119
120
  def initialize(context_data)
120
121
  @context = LightService::Context.make(context_data)
121
122
  end
123
+ # rubocop:enable Lint/MissingSuper
122
124
 
123
125
  def violated_keys
124
126
  context.keys.map(&:to_sym) & reserved_keys
@@ -1,16 +1,15 @@
1
- require 'active_support/deprecation'
2
-
3
1
  module LightService
4
2
  module Outcomes
5
3
  SUCCESS = 0
6
4
  FAILURE = 1
7
5
  end
8
6
 
9
- # rubocop:disable ClassLength
7
+ # rubocop:disable Metrics/ClassLength
10
8
  class Context < Hash
11
9
  attr_accessor :message, :error_code, :current_action, :around_actions,
12
10
  :organized_by
13
11
 
12
+ # rubocop:disable Metrics/ParameterLists, Lint/MissingSuper
14
13
  def initialize(context = {},
15
14
  outcome = Outcomes::SUCCESS,
16
15
  message = '',
@@ -22,6 +21,7 @@ module LightService
22
21
 
23
22
  context.to_hash.each { |k, v| self[k] = v }
24
23
  end
24
+ # rubocop:enable Metrics/ParameterLists, Lint/MissingSuper
25
25
 
26
26
  def self.make(context = {})
27
27
  unless context.is_a?(Hash) || context.is_a?(LightService::Context)
@@ -57,9 +57,9 @@ module LightService
57
57
  end
58
58
 
59
59
  def outcome
60
- msg = '`Context#outcome` attribute reader is ' \
61
- 'DEPRECATED and will be removed'
62
- ActiveSupport::Deprecation.warn(msg)
60
+ warning_msg = '`Context#outcome` attribute reader is ' \
61
+ 'DEPRECATED and will be removed'
62
+ LightService::Deprecation.warn(warning_msg)
63
63
  @outcome
64
64
  end
65
65
 
@@ -101,7 +101,7 @@ module LightService
101
101
  def skip_all!(message = nil)
102
102
  warning_msg = "Using skip_all! has been deprecated, " \
103
103
  "please use `skip_remaining!` instead."
104
- ActiveSupport::Deprecation.warn(warning_msg)
104
+ LightService::Deprecation.warn(warning_msg)
105
105
 
106
106
  skip_remaining!(message)
107
107
  end
@@ -152,13 +152,8 @@ module LightService
152
152
  end
153
153
 
154
154
  def inspect
155
- "#{self.class}(#{self}, " \
156
- + "success: #{success?}, " \
157
- + "message: #{check_nil(message)}, " \
158
- + "error_code: #{check_nil(error_code)}, " \
159
- + "skip_remaining: #{@skip_remaining}, " \
160
- + "aliases: #{@aliases}" \
161
- + ")"
155
+ "#{self.class}(#{self}, success: #{success?}, message: #{check_nil(message)}, error_code: " \
156
+ "#{check_nil(error_code)}, skip_remaining: #{@skip_remaining}, aliases: #{@aliases})"
162
157
  end
163
158
 
164
159
  private
@@ -169,5 +164,5 @@ module LightService
169
164
  "'#{value}'"
170
165
  end
171
166
  end
172
- # rubocop:enable ClassLength
167
+ # rubocop:enable Metrics/ClassLength
173
168
  end
@@ -0,0 +1,17 @@
1
+ module LightService
2
+ module Deprecation
3
+ class << self
4
+ # Basic implementation of a deprecation warning
5
+ def warn(message, callstack = caller)
6
+ # Construct the warning message
7
+ warning_message = "DEPRECATION WARNING: #{message}\n"
8
+ warning_message += "Called from: #{callstack.first}\n" unless callstack.empty?
9
+
10
+ # Output the warning message to stderr or a log file
11
+ warn warning_message
12
+
13
+ # Additional logging or actions can be added here
14
+ end
15
+ end
16
+ end
17
+ end
@@ -1,7 +1,11 @@
1
1
  module LightService
2
2
  class FailWithRollbackError < StandardError; end
3
+
3
4
  class ExpectedKeysNotInContextError < StandardError; end
5
+
4
6
  class PromisedKeysNotInContextError < StandardError; end
7
+
5
8
  class ReservedKeysInContextError < StandardError; end
9
+
6
10
  class UnusableExpectKeyDefaultError < StandardError; end
7
11
  end
@@ -0,0 +1,46 @@
1
+ module LightService
2
+ module I18n
3
+ class LocalizationAdapter
4
+ def failure(message_or_key, action_class, i18n_options = {})
5
+ find_translated_message(message_or_key,
6
+ action_class,
7
+ i18n_options,
8
+ :type => :failure)
9
+ end
10
+
11
+ def success(message_or_key, action_class, i18n_options = {})
12
+ find_translated_message(message_or_key,
13
+ action_class,
14
+ i18n_options,
15
+ :type => :success)
16
+ end
17
+
18
+ private
19
+
20
+ def find_translated_message(message_or_key,
21
+ action_class,
22
+ i18n_options,
23
+ type)
24
+ if message_or_key.is_a?(Symbol)
25
+ i18n_options.merge!(type)
26
+ translate(message_or_key, action_class, i18n_options)
27
+ else
28
+ message_or_key
29
+ end
30
+ end
31
+
32
+ def translate(key, action_class, options = {})
33
+ type = options.delete(:type)
34
+
35
+ scope = i18n_scope_from_class(action_class, type)
36
+ options[:scope] = scope
37
+
38
+ ::I18n.t(key, **options)
39
+ end
40
+
41
+ def i18n_scope_from_class(action_class, type)
42
+ "#{action_class.name.underscore}.light_service.#{type.to_s.pluralize}"
43
+ end
44
+ end
45
+ end
46
+ end
@@ -1,44 +1,31 @@
1
1
  module LightService
2
2
  class LocalizationAdapter
3
- def failure(message_or_key, action_class, i18n_options = {})
3
+ def failure(message_or_key, action_class)
4
4
  find_translated_message(message_or_key,
5
- action_class,
6
- i18n_options,
7
- :type => :failure)
5
+ action_class.to_s.underscore,
6
+ :failures)
8
7
  end
9
8
 
10
- def success(message_or_key, action_class, i18n_options = {})
9
+ def success(message_or_key, action_class)
11
10
  find_translated_message(message_or_key,
12
- action_class,
13
- i18n_options,
14
- :type => :success)
11
+ action_class.to_s.underscore,
12
+ :successes)
15
13
  end
16
14
 
17
15
  private
18
16
 
19
- def find_translated_message(message_or_key,
20
- action_class,
21
- i18n_options,
22
- type)
17
+ def find_translated_message(message_or_key, action_class, type)
23
18
  if message_or_key.is_a?(Symbol)
24
- i18n_options.merge!(type)
25
- translate(message_or_key, action_class, i18n_options)
19
+ LightService::LocalizationMap.instance.dig(
20
+ LightService::Configuration.locale,
21
+ action_class.to_sym,
22
+ :light_service,
23
+ type,
24
+ message_or_key
25
+ )
26
26
  else
27
27
  message_or_key
28
28
  end
29
29
  end
30
-
31
- def translate(key, action_class, options = {})
32
- type = options.delete(:type)
33
-
34
- scope = i18n_scope_from_class(action_class, type)
35
- options[:scope] = scope
36
-
37
- I18n.t(key, **options)
38
- end
39
-
40
- def i18n_scope_from_class(action_class, type)
41
- "#{action_class.name.underscore}.light_service.#{type.to_s.pluralize}"
42
- end
43
30
  end
44
31
  end
@@ -0,0 +1,7 @@
1
+ require 'singleton'
2
+
3
+ module LightService
4
+ class LocalizationMap < Hash
5
+ include ::Singleton
6
+ end
7
+ end